A report can customize the message body used when an email for that report is
sent. RStudio Connect uses the output metadata entry named
rsc_email_body_text
for plain-text bodies and rsc_email_body_html
for HTML
bodies. A report with neither entry uses an automatically generated,
plain-text body with a link to the report’s URL.
Text Message Bodies
Use the YAML header to specify a simple, static text override of the email
body:
---
title: "Report Title"
rmd_output_metadata:
rsc_email_body_text: "Here is my custom email message.
YAML requires a full blank line like the one above to start a new line."
---
The message in the email client would look similar to the following:
Here is my custom email message.
YAML requires a full blank line like the one above to start a new line.
Set the body text in an R code chunk if you need to dynamically build the
message:
changePercent <- 20
body <- paste("Sales changed by ", changePercent, "%.", sep = "")
rmarkdown::output_metadata$set(rsc_email_body_text = body)
You can also read the current body from the output metadata to
incrementally compose a final body.
widgetOrders <- 42
body <- rmarkdown::output_metadata$get("rsc_email_body_text")
body <- sprintf("%s\n\nThere were %d widget sales.", body, widgetOrders)
rmarkdown::output_metadata$set(rsc_email_body_text = body)
The glue
package can help with more complicated
formatting.
library(glue)
widgetOrders <- 42
changePercent <- 20
body <- glue(
'Sales changed by {changePercent}%.\n\n',
'There were {widgetOrders} widget sales.')
rmarkdown::output_metadata$set(rsc_email_body_text = body)
HTML Message Bodies
The rsc_email_body_html
attribute specifies an HTML-formatted message body.
RStudio Connect sets the content-type of the message so that most email
clients will display the HTML message correctly.
Use rsc_email_body_text
together with rsc_email_body_html
to supply text
that older email clients can display while allowing newer clients to display
your rich content.
The YAML header can specify a simple, static HTML override of the email body:
---
title: "Report Title"
rmd_output_metadata:
rsc_email_body_html: "<strong>The new report is ready!</strong>"
---
You can build the HTML message dynamically:
library(htmltools)
changePercent <- 20
body <- paste(
h1("Sales Update"),
p("Sales changed by ",
em(paste0(changePercent, "%"))),
sep = "\n")
rmarkdown::output_metadata$set(rsc_email_body_html = body)
Composing and styling HTML email messages is different than building
traditional web pages. Email messages cannot embed scripts nor reference
external stylesheets. Email clients may implement additional restrictions.
Not all email clients display HTML messages exactly the same. Send yourself
a test message to check basic formatting, then confirm with your audience
that the message appears correctly in their email client.
Embedding Images in HTML Email
It is possible to embed images, such as plots, within HTML email, using the
rsc_email_images
attribute in rmd_output_metadata
. The embedded image must
have a Content ID that is used in the body of the HTML and when providing the
image to rsc_email_images
, and the image itself must be base64-encoded. Here
is an example:
library(ggplot2)
library(htmltools)
# Create a plot.
car_plot <-
ggplot(data = mtcars,
aes(
x = disp,
y = hp,
color = wt,
size = mpg
)) +
geom_point()
# Save the plot to disk as a PNG image.
ggplot2::ggsave(
"plot.png",
plot = car_plot,
device = "png",
width = 5,
height = 5,
dpi = "screen"
)
# Encode the PNG image as base64.
plot_base64 <- base64enc::base64encode("plot.png")
# Construct the HTML email message.
message <- paste(h1("mtcars data plot"),
# Use the filename "plot.png" as the Content ID by using "cid:"
# in the image tag's "src" attribute:
p(img(src = "cid:plot.png")),
sep = "\n")
# Create the data structure to hold the embedded image.
images <- list(plot.png = plot_base64)
# Give RStudio Connect the message and image data for the HTML email.
rmarkdown::output_metadata$set(rsc_email_body_html = message)
rmarkdown::output_metadata$set(rsc_email_images = images)

R Markdown itself does not currently generate email-friendly HTML output,
which is why RStudio Connect cannot use the generated report as the email
body.
Building a correct, email-friendly HTML message with images can be complex,
but the R package blastula
,
described in the next section, can simplify the process.
Simplifying HTML Email Creation with Blastula
The blastula
package makes it
easy to compose HTML email from R. It can style your message in a way that
renders correctly across a variety of clients, and it can handle many of the
details of structuring the HTML and embedding images.
Use blastula
version 0.2.1 or newer.
# Blastula example adapted from https://github.com/rich-iannone/blastula
library(blastula)
library(formattable)
# Create a data frame.
df <- data.frame(
Name = c(
"Bob",
"Ashley",
"James",
"David",
"Jenny",
"Hans",
"Leo",
"John",
"Emily",
"Lee"
),
Overall = c("C", "A", "A", "C", "B", "B", "B", "A", "C", "C"),
Q1_Sales = c(8.9, 9.5, 9.6, 8.9, 9.1, 9.3, 9.3, 9.9, 8.5, 8.6),
Q2_Sales = c(9.1, 9.1, 9.2, 9.1, 8.9, 8.5, 9.2, 9.3, 9.1, 8.8),
Projection = c(9, 9.3, 9.4, 9, 9, 8.9, 9.25, 9.6, 8.8, 8.7),
Tracking = c(TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE),
stringsAsFactors = FALSE
)
# Create an HTML table with `format_table()`.
formatted_table <-
format_table(
x = df,
list(
Overall =
formatter("span",
style = x ~ ifelse(
x == "A",
style(color = "green", font.weight = "bold"), NA
)),
area(col = c(Q1_Sales, Q2_Sales)) ~ normalize_bar("pink", 0.2),
Projection =
formatter(
"span",
style = x ~ style(color = ifelse(rank(-x) <= 3, "green", "gray")),
x ~ sprintf("%.2f (rank: %02d)", x, rank(-x))
),
Tracking =
formatter(
"span",
style = x ~ style(color = ifelse(x, "green", "red")),
x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "Yes", "No"))
)
)
)
# Create the Blastula email object.
message <- compose_email(
body = "
Hi Jim,
The fiscal quarter closes next week. Here are the \\
the sales rep numbers.\\
{formatted_table}
<br />
Cheers,<br /> EVP of Sales"
)
# Use Blastula's message as the email body in RStudio Connect.
rmarkdown::output_metadata$set(rsc_email_body_html = message$html_str)
rmarkdown::output_metadata$set(rsc_email_images = message$images)
The output will be formatted for an email client:

You can also embed images and plots in your HTML email.
library(blastula)
library(ggplot2)
# Create a ggplot plot object.
car_plot <-
ggplot(data = mtcars,
aes(
x = disp,
y = hp,
color = wt,
size = mpg
)) +
geom_point()
# Use the `add_ggplot()` helper function inside the email message body.
email <- compose_email(
body = "
New data is available!
This plot summarizes the new data:
{add_ggplot(plot_object = car_plot, width = 5, height = 5)}
Cheers
"
)
# Give the HTML email data to RStudio Connect.
rmarkdown::output_metadata$set(rsc_email_body_html = email$html_str)
rmarkdown::output_metadata$set(rsc_email_images = email$images)

For consistency, you can always assign both rsc_email_body_html
and
rsc_email_images
at the end of your R Markdown report when working with
Blastula, even if initially it does not contain embedded images:
email <- blastula::compose_email(...)
rmarkdown::output_metadata$set(rsc_email_body_html = email$html_str)
rmarkdown::output_metadata$set(rsc_email_images = email$images)
See the blastula
site at https://github.com/rich-iannone/blastula for more
information and examples.