\mainmatter

Get Started

In this chapter, we show how to create a simple website from scratch using blogdown. The website will contain a home page, an "About" page, one R Markdown post, and two plain Markdown posts. You will learn the basic concepts for creating websites with blogdown.

We recommend using the RStudio IDE with blogdown because there are a number of features built-in to the R package that RStudio users can take advantage of, but it is not required. Using the RStudio IDE will make some steps in this workflow easier, but you are free to use any editor.

Installation

We assume you have already installed:

If you are not using the RStudio IDE, please install Pandoc\index{Pandoc} (http://pandoc.org). Instructions are available on the reference site (https://pandoc.org/installing.html).

The blogdown package is available on CRAN and you can install it with:

install.packages('blogdown') 

Installation troubleshooting

Do you have an old version of blogdown? Compare your version against ours and upgrade if necessary.

packageVersion("blogdown")
packageVersion("blogdown")[, 1:2]

To update blogdown, run install.packages('blogdown').

Do you have old versions of blogdown's dependencies (such as rmarkdown)? If you are experiencing problems, you may first try to update all R packages:

update.packages(ask = FALSE, checkBuilt = TRUE)

If you are still experiencing issues with blogdown, you may try installing the development version from GitHub:

if (!requireNamespace('remotes')) install.packages('remotes')
remotes::install_github('rstudio/blogdown')

If you use RStudio, it will remind you of restarting R before installing or updating any packages currently in use. If you do not use RStudio, you may need to restart R by yourself.

A quick example

In this section, we aim to take you from no website to a basic blogdown website, with minimal time and friction. We will briefly run through the development of a working but simple website using the default theme used by the blogdown package.

This section is designed to provide a beginner-friendly workflow. In later sections, we will present different workflows and dive deeper into details like advanced blogdown features, Hugo themes, the Hugo static site generator, version control, and deployment options.

Prerequisites

To keep this example actually quick, we will assume that you are using the RStudio IDE and will rely on some of the built-in features that help blogdown users.^[The instructions here rely on a recent RStudio IDE version, v1.4.1106. You may download all RStudio official releases from https://posit.co/download/rstudio-desktop/.]

We also assume that you have followed the installation instructions in Section \@ref(installation).

Create project

The best home for your new blogdown website project is inside an RStudio project. A quick way to create one is to use the RStudio New Project Wizard (File -> New Project -> New Directory) (see Figure \@ref(fig:new-project) and \@ref(fig:blogdown-project)).

knitr::include_graphics('images/new-project.png')
knitr::include_graphics('images/blogdown-project.png')

Click "Create Project". The project wizard then runs a function that creates a new site for you by doing the following steps:

  1. Creates and opens a new RStudio Project for the website;
  2. Downloads and installs the default theme (called hugo-lithium) with an example site;
  3. Adds a sample .Rmd post;
  4. Creates a netlify.toml file to help you deploy your site to Netlify, and
  5. Creates an .Rprofile file to set your blogdown options (some have been set up for you).

If you are not using RStudio, you can create a new empty directory, and call the new_site() function in the directory in the R console to create a new site project:

blogdown::new_site()

You should now see a bunch of directories and files under the site project. The project will include the following files:

After all this, your new site is ready!

Serve site

Before we explain these new directories and files, let's use our first blogdown function. It's an important one, and it is often the first one you use when you open up a blogdown project to start a local preview of your website.

You can use run blogdown::serve_site() from the console or equivalently, click on the RStudio addin "Serve Site" (see Figure \@ref(fig:addin-serve)).

knitr::include_graphics('images/addin-serve.png')

Then you should see something that looks like Figure \@ref(fig:serve-site).

knitr::include_graphics('images/serve-site.png')

Serving the site did the following:

  1. Started a local Hugo server to help you preview your website, and
  2. Knitted a sample .Rmd post to an .html page. You can see this from the progress message that printed to your console: Rendering content/post/2020-12-01-r-rmarkdown/index.Rmd... Done.

If you want to preview your site locally in your web browser, you may click on the "Show in new window" icon at the top of your RStudio viewer pane (to the right of the broom icon). You can see what the site looks like in Figure \@ref(fig:lithium).

knitr::include_graphics('images/lithium-theme.png')

Let's introduce an important and helpful technology that you just used: LiveReload.\index{LiveReload} Serving your site uses LiveReload, which means your website^[Until you set up your website to be deployed, LiveReload only updates the local version of your website. This version is only visible to you. In order to make your website searchable, discoverable, and live on the Internet, you will need to upload your website's files to a site builder. See Chapter \@ref(deployment) for details.] will be automatically rebuilt and reloaded in your web browser^[You can also think of the RStudio Viewer as a web browser.] when you modify any source file of your website and save it. Basically, once you launch the website in a web browser, you do not need to rebuild it explicitly anymore. All you need to do is edit the source files, such as R Markdown documents, and save them. There is no need to click any buttons or run any commands. LiveReload is implemented via blogdown::serve_site()\index{blogdown::serve_site()} and Hugo, and you will only need to use it once per work session.

Edit content

Now let's see LiveReload in action. In your files pane, navigate inside the content/ folder. This folder is where all your site's content lives. Find and open the file content/post/2020-12-01-r-rmarkdown/index.Rmd. This is a sample R Markdown post that is added by blogdown by default when you set up a new site.

When you open that file, you will notice a YAML block at the top with familiar metadata like title and author, then code chunks and narrative text below the YAML as with your typical R Markdown file.

Let's edit this index.Rmd post. This post is a Hugo page bundle. Each post gets its own bundle, or folder. Inside the post bundle is where your static post-specific files like images and .csv data files should go.

content/
├── post
│   ├── 2020-12-01-r-rmarkdown
│   │   ├── index.html <- blogdown knitted this for you
│   │   └── index.Rmd
│   ├── 2015-01-01-lorem-ipsum
│   └── 2016-12-30-hello-markdown

The default behavior of blogdown is to automatically knit posts that have not been knitted before when you serve your site, so this file has already been knitted---that is why you can see it in your local preview.

Go ahead and add an R code chunk to this file, like:

```r`r ''`
summary(Orange)
```

If you save the file with this edit, blogdown will re-knit the file on save, and your website preview should update after a few seconds once LiveReload kicks in.

Try it again! Add another R code chunk like:

```r`r ''`
library(ggplot2)
ggplot(Orange, aes(x = age, 
                   y = circumference, 
                   color = Tree)) +
  geom_point() +
  geom_line() +
  guides(color = "none") +
  theme_bw()
```

You should see a blog post that looks like Figure \@ref(fig:edit-content).

knitr::include_graphics('images/edit-content.png')

When in doubt, run blogdown::check_site()

There are many possible reasons why a website does not work as expected. For example, you may have misconfigured certain options in the website configuration file (such as config.yaml), or marked a post as draft but forgetten to unmark it before publishing the site. It is easy to make these mistakes, and often hard to diagnose them.

Fortunately, the function blogdown::check_site() can run a series of checks in your website project to help you identify common problems. It also provides tips on how to fix these problems. It is meant to be used during your interactive work sessions. You will see what files were checked, which checks were successful, and blogdown will offer [TODO] items when a check needs your attention, like this:

-----------------------------------------------------------
○ A successful check looks like this.
● [TODO] A check that needs your attention looks like this.
| Let's check out your blogdown site!
-----------------------------------------------------------
― Checking config.yaml
| Checking "baseURL" setting for Hugo...
○ Found baseURL = "https://yihui.org/"; nothing to do here!
....
― Check complete: config.yaml

― Checking .gitignore
| Checking for items to remove...
○ Nothing to see here - found no items to remove.
| Checking for items to change...
● [TODO] Change items in .gitignore: public -> /public,
  blogdown -> /blogdown
| Checking for items you can safely ignore...
● [TODO] You can safely add to .gitignore: .DS_Store, Thumbs.db
....
― Check complete: .gitignore

― Checking Hugo
| Checking Hugo version...
○ Found 8 versions of Hugo. You are using Hugo 0.82.1.
| Checking .Rprofile for Hugo version used by blogdown...
| Hugo version not set in .Rprofile.
● [TODO] Set options(blogdown.hugo.version = "0.82.1") in .Rprofile
  and restart R.
― Check complete: Hugo

― Checking netlify.toml...
○ Found HUGO_VERSION = 0.25.1 in [build] context of netlify.toml.
....
― Check complete: netlify.toml

― Checking content files
| Checking for validity of YAML metadata in posts...
○ All YAML metadata appears to be syntactically valid.
| Checking for previewed content that will not be published...
○ Found 0 files with future publish dates.
● [TODO] Found 2 files marked as drafts. To un-draft, run:

  blogdown::edit_draft(c(
  "content/foo.md",
  "content/bar.md"
  ))

  and change a file's YAML from 'draft: true' to 'draft: false'.
....
― Check complete: Content

Configure site

We have just shown you how you can start adding .Rmd content to your website. However, when you are first setting up your site, you will want to edit a few other files to personalize your site. The config.yaml file stores your website configurations for Hugo and for your Hugo theme. You will usually only edit this file during the initial site setup.

For example, you may see configurations like these in config.yaml:

baseurl: /
title: A Hugo website
theme: hugo-lithium
ignoreFiles:
  - \.Rmd$
  - \.Rmarkdown$
  - _cache$
  - \.knit\.md$
  - \.utf8\.md$
permalinks:
  post: /:year/:month/:day/:slug/
menu:
  main:
    - name: About
      url: /about/
    - name: GitHub
      url: https://github.com/rstudio/blogdown
    - name: Twitter
      url: https://twitter.com/rstudio

You can change the website title, e.g., title: "My own cool website", and update the GitHub and Twitter URLs.

Summary

You have now learned three of the most basic concepts for a Hugo-based website:

  1. How to preview your Hugo site locally using blogdown::serve_site() or the RStudio addin "Serve Site."

  2. How to edit the Hugo configuration file config.yaml\index{config.yaml} to specify global settings for your site and your theme.

  3. How to edit contents inside the content/ directory, where you write the R Markdown or Markdown source files for your posts and pages. Under content/ of the default site, you can see about.md and a post/ directory containing a few posts. The organization of the content directory is up to you. You can have arbitrary files and directories there, depending on the website structure you want.

What is next?

If you are satisfied with this default theme, you are basically ready to start writing and publishing your new website! There are many options for publishing static websites like this one, and we will talk more about them in Chapter \@ref(deployment) if you are not familiar with deploying websites.

We will also show how to use other themes in Section \@ref(other-themes). However, please keep in mind that a more complicated and fancier theme may require you to learn more about all the underlying technologies like the Hugo templating language, HTML, CSS, and JavaScript.

A quick deploy

Publishing a blogdown website involves copying the output directory containing all your rendered site files (typically, a bunch of *.html files and site assets like fonts, CSS, JavaScript, and images) to a web server or web hosting service.

In this section, we will walk you through a quick deploy to publish your website using a drag-and-drop tool from \index{Netlify} https://www.netlify.com. Netlify is a platform that offers cloud hosting and serverless backend services for static websites. Lucky for us, that is exactly what we need---since blogdown helps us create static websites using Hugo.

If you followed along with Section \@ref(a-quick-example), you should now have s static website using the Hugo lithium theme with knitted .Rmd content for one post and served locally using blogdown.

The drag-and-drop method we describe next is a good workflow to start with if you are not familiar with GIT or GitHub or deploying websites. There are many options for publishing static websites, and we will talk more about them plus advanced workflows involving version control and continuous deployment in Chapter \@ref(deployment).

Build site

The publishing directory of a Hugo site is public/ by default. Your built website will be generated to this directory, which you can upload to any web server that can serve static websites, and your website will be up and running.

Serving your Hugo site locally using blogdown::serve_site() does not generate the public/ directory. To follow this drag-and-drop method, you'll need to build your site locally first.

Restart the R session, and run:

blogdown::build_site()

Alternatively, if you use RStudio, you may use:

You should see a new public/ directory under the root directory of your project. Never edit files in this directory, as your changes will always be overwritten whenever you re-build your site.

Note that this function does not re-knit R Markdown files by default, because it may be expensive and often undesirable to render .Rmd files that have been knitted before. Given that R package upgrades have a tendency to break older code, continuously re-knitting old content is nearly impossible to do without errors, especially over longer periods of time.

We recommend always using blogdown::serve_site() first to preview your site before building it. By default, that function will knit your R Markdown content that has not been knitted yet. As mentioned earlier, we also recommend running blogdown::check_content(). Among other things, we check if you have content that needs to be re-knit:

| Checking your R Markdown content...
○ All R Markdown files have been knitted.
○ All R Markdown output files are up to date with their source files.

Use Netlify Drop

Next, go online to\index{Netlify} Netlify Drop at https://app.netlify.com/drop. You can drag and drop the public/ folder from your file viewer to the indicated area on the Netlify web page, where it says "Drag and drop your site output folder here."

Wait for a few seconds for Netlify to deploy the files, and it will assign a random subdomain of the form random-word-12345.netlify.app to you. After your site is live, you will be able to share the link to your new blogdown site if you would like to.

You will notice a disclaimer that this site will be deleted after 24 hours. You need to create an account to save this link and keep your site online.

Sign up for Netlify

Netlify has a free plan with plenty of useful features, so we recommend signing up for an account. To sign up:

  1. Go online to \index{Netlify} https://www.netlify.com.

  2. Click on the "Sign Up" button.

  3. If you have a GitHub account (https://github.com), we recommend signing up using your existing GitHub account (no need to create another account), so select "GitHub" (you may need to sign in), and click to "Authorize Netlify."

  4. From your account, if you used Netlify Drop, you can (and should) change your random subdomain to a more meaningful one. You may read the docs for changing a site's default Netlify subdomain here: https://docs.netlify.com/domains-https/custom-domains/#assign-a-domain-to-a-site

  5. Also from your account, you may update your existing site by making changes locally, reknitting if necessary, then rebuilding your site with blogdown::build_site(). In the "Deploys" tab on Netlify, scroll down to where you see "Need to update your site? Drag and drop your site output folder here." Drop your updated public/ folder there to update the deployed website.

What is next?

The workflow described above can be cumbersome the more you work on your website. It can be much easier to publish a website if you are familiar with GIT and GitHub.

We recommend that you create a new site on Netlify from your GitHub repository that contains the source files of your website, so that you can enjoy the benefits of continuous deployment instead of manually uploading the public/ folder every time.

With this advanced workflow, you do not need to run blogdown::hugo_build() locally, because the website can be built on Netlify via Hugo. Instead, you would rely on blogdown::serve_site() locally to preview your site before pushing your changes to GitHub. See Chapter \@ref(deployment) for more information.

RStudio IDE

There are a few essential RStudio addins\index{RStudio addins} to make it easy to edit and preview your website, and you can find them in the menu "Addins" on the RStudio toolbar:

knitr::include_graphics('images/new-post.png')
knitr::include_graphics('images/update-meta.png')
knitr::include_graphics('images/insert-image.png')
knitr::include_graphics('images/overwrite-image.png')

With these addins, you should rarely need to run any R commands manually after you have set up your website, since all your posts will be automatically compiled whenever you create a new post or modify an existing post due to the LiveReload feature.

If your website was created using the function blogdown::new_site() instead of the RStudio menu (see Figure \@ref(fig:new-project) and \@ref(fig:blogdown-project)) for the first time, you can quit RStudio and open the project again. If you go to the menu Tools -> Project Options, your project type should be "Website" like what you can see in Figure \@ref(fig:project-options).

Then you will see a pane in RStudio named "Build," and there is a button "Build Website." When you click this button, RStudio will call blogdown::build_site() to build the website. This will automatically generate files in the public/ directory.^[Or wherever your publishing directory is located. It is public/ by default, but it can be changed by specifying the field publishDir: "myNewDirectory" in the config.yaml file.]

We strongly recommend that you uncheck the option "Preview site after building" in your RStudio project options (Figure \@ref(fig:project-options)).^[In case you wonder why: unless you have set the option relativeurls to true in config.toml, it requires a web server to preview the website locally, otherwise even if you can see the homepage of your website in the RStudio Viewer, most links like those links to CSS and JavaScript files are unlikely to work. When the RStudio Viewer shows you the preview, it does not actually launch a web server.] You can also uncheck the option "Re-knit current preview when supporting files change," since this option is not really useful after you call serve_site().

knitr::include_graphics('images/project-options.png')

Global options\index{Global Options}

The blogdown package uses global options, specified in a .Rprofile file, to help users customize how blogdown works. When you create a new site, blogdown adds a project-level .Rprofile file in the root directory of your website project.

Options should be set using the syntax options(name = value), and those included in a new blogdown site's .Rprofile file are presented in Table \@ref(tab:global-options-new).

knitr::kable(matrix(c(
  'blogdown.hugo.version', 'A valid Hugo version', 'A Hugo version number',
  'blogdown.knit.on_save', 'TRUE', 'Knit Rmd files automatically on save?',
  'blogdown.method', 'markdown', 'The output format of .Rmd posts',
  'blogdown.serve_site.startup', 'FALSE', 'Serve the site on RStudio startup?',
  NULL
), ncol = 3, byrow = TRUE, dimnames = list(NULL, c('Option name', 'Default', 'Meaning'))), booktabs = TRUE, caption = 'Global options for configured for new blogdown sites.')

Three of these options are worth further explanations:

We recommend that you set these options in your R startup profile file. If you have never used a startup profile file before, you can check out the help page ?Rprofile. Here, we provide a brief but incomplete introduction to orient you quickly.

A startup profile file is basically an R script that is executed when your R session is started. This is a perfect place to set global options, so you do not need to type these options again every time you start a new R session.

There are a few things you need to know about R's startup profile file before using:

  1. You can use a global profile file ~/.Rprofile,^[The tilde ~ denotes your home directory in your system.] or a per-project file .Rprofile under the root directory of your RStudio project. The former will be applied to all R sessions that you start, unless you have provided the latter to override it.

  2. The name "startup profile file" means that R only executes this file when you first start your R session. This means that when you modify and save your .Rprofile, you must restart R for the changes to take effect.

  3. R will silently ignore the last line of your .Rprofile if it does not have a trailing newline, so please make sure you add at least one newline to the end of your .Rprofile.

If you want to add a profile file to an existing blogdown project, or you created a new website without using blogdown::new_site(), you can create a boilerplate version with this command in your R console:

blogdown::config_Rprofile()

This is the easiest way to create or modify a per-project profile file. At the top of the file in a new blogdown website project, you will see this:

# REMEMBER to restart R after you modify and save this file!

# First, execute the global .Rprofile if it exists. You may
# configure blogdown options there, too, so they apply to any
# blogdown projects. Feel free to ignore this part if it sounds
# too complicated to you.
if (file.exists("~/.Rprofile")) {
  base::sys.source("~/.Rprofile", envir = environment())
}

First, note the top message! The next section of code is necessary to execute both your project profile as well as the global profile if one exists. R only reads one startup profile file. For example, if you have a .Rprofile under the current directory and a global ~/.Rprofile, only the former one will be executed when R starts up from the current directory. This code is provided for you so you may execute both a global and per-project profile file. Note that this code should only live in the project profile, and you must not add it to your global ~/.Rprofile, otherwise it will trigger an infinite recursion.

Below that, you will set your options. These can be stacked on separate lines, or you may use commas to list multiple options together:

# stacked options
options(blogdown.serve_site.startup = FALSE)
options(blogdown.knit.on_save = TRUE)

# comma-separated options
options(blogdown.serve_site.startup = FALSE,
        blogdown.knit.on_save = TRUE)

It is up to you how to format your profile file---either way works. The blogdown options provided in the boilerplate profile file are just a subset of the options available. Depending on your personal preferences and the theme you choose, you may wish to set more global options as you work on your website. For example:

knitr::kable(matrix(c(
  'blogdown.author', '', 'The default author of new posts',
  'blogdown.ext', '.md', 'Default extension of new posts: .md / .Rmd / .Rmarkdown',
  'blogdown.subdir', 'post', 'Default subdirectory under content/ for new posts',
  'blogdown.yaml.empty', TRUE, 'Preserve empty fields in YAML?',
  NULL
), ncol = 3, byrow = TRUE, dimnames = list(NULL, c('Option name', 'Default', 'Meaning'))), booktabs = TRUE, caption = 'Additional global options that affect the behavior of blogdown.')

Suppose you always prefer writing .Rmd posts (instead of the default .md), and want the author of new posts to be "John Doe" by default. You can set these options in the profile file:

options(blogdown.ext = '.Rmd', blogdown.author = 'John Doe', blogdown.subdir = 'blog')

A nice consequence of setting these options is that when you use the RStudio addin "New Post," the fields "Author," "Subdirectory," and "Format" will be automatically populated, so you do not need to manipulate them every time, unless you want to change the defaults.

One inconvenience when using startup profile files is the case of the team-authored blog, where multiple authors collaborate on the same website project. You cannot set author-specific options using the blogdown.author option in a single .Rprofile, because this option should be different for different authors. One workaround is to set common website options in your project .Rprofile, then allow each individual author to set their own author-specific options in the global ~/.Rprofile on each author's computer. If you use the boilerplate blogdown::config_Rprofile(), the first chunk of code at the top will ensure that the global ~/.Rprofile is also executed if it exists.

R Markdown vs. Markdown {#output-format}

If you are not familiar with R Markdown\index{R Markdown}, please see Appendix \@ref(r-markdown) for a quick tutorial. When you create a new post, you have to decide whether you want to use R Markdown or plain Markdown\index{Markdown}, as you can see from Figure \@ref(fig:new-post).

Table \@ref(tab:md-diff) summarizes the main differences among the three file extensions. Note that .Rmarkdown is always rendered to Markdown (.markdown), yet .Rmd may be rendered to HTML or Markdown, depending on the global option blogdown.method = "html" or "markdown".

Table: (#tab:md-diff) Differences among the three document formats.

|Feature |.Rmd |.Rmarkdown |.md/.markdown | |:------------|:----|:----------|:----| |Run R code |yes |yes |no | |Bibliography |yes |yes |no | |Cross references | yes | yes |no | |LaTeX math |yes |maybe |maybe| |HTML widgets |yes |yes |no |

Basically, you cannot execute any R code in a plain Markdown document (.md or .markdown), whereas in an R Markdown document (.Rmd or .Rmarkdown), you can embed R code chunks (```r). However, you can still embed R code in plain Markdown using the syntax for fenced code blocks ```r (note there are no curly braces {}). Such code blocks will not be executed and may be suitable for pure demonstration purposes. Below is an example of an R code chunk in R Markdown:

````{verbatim, lang='markdown'}

plot(cars, pch = 20)  # not really cool
And here is an example of an R code block in plain Markdown:

````{verbatim, lang='markdown'}
```r
1 + 1  # not executed
```

A plain Markdown post is directly rendered to HTML through Goldmark \index{Goldmark}(a Markdown renderer written in the Go language and adopted by Hugo). An R Markdown post is first compiled to Markdown through the R packages rmarkdown and bookdown, which means you can use most features of bookdown's Markdown extensions in blogdown. Then the Markdown post can be rendered to HTML by either Goldmark or Pandoc\index{Pandoc}. For the latter case, you can also use richer features in Pandoc's Markdown (see Section \@ref(blogdown-method) for more information).

Basic features of R Markdown

If you use R Markdown [@R-rmarkdown] with blogdown, we recommend that you read the documentation of Pandoc and bookdown at least once to know all the possible features. We will not repeat the details in this book, but list the features briefly below, which are also demonstrated on the example website https://blogdown-demo.rbind.io.

If you do not need the extra features in Table \@ref(tab:md-diff), you can just write a plain Markdown post (.md), otherwise you need to use R Markdown. As we mentioned before, there are two possible formats of R Markdown: one with the file extension .Rmd, and one with .Rmarkdown. The latter is always rendered to Markdown, which will be processed by Hugo's Markdown renderer (Goldmark). The former can be rendered to either HTML or Markdown, which we will explain in the next section.

Render R Markdown to Markdown or HTML? {#blogdown-method}

If you use the file extension .Rmd for a post, you need to make a decision on whether to render it to .html or .md. Essentially, that means whether you want to use Pandoc or Goldmark to render the post. To render to .html via Pandoc, you need to set the global option options(blogdown.method = "html"). To render to .md, you can set options(blogdown.method = "markdown").

In general, Pandoc's Markdown features are richer than Goldmark's. For example, Goldmark does not support LaTeX math and Pandoc does. We have added the MathJax \index{MathJax} support to the default theme (hugo-lithium) in blogdown to render LaTeX math on HTML pages, but there is a caveat for plain Markdown posts: you have to include inline math expressions in a pair of backticks `$math$`, e.g., `$S_n = \sum_{i=1}^n X_i$`. Similarly, math expressions of the display style have to be written in `$$math$$`. For .Rmd posts to be rendered to .html, you can use $math$ for inline math expressions, and $$math$$ for display-style expressions.^[The reason that we need the backticks for plain Markdown documents is that we have to prevent the LaTeX code from being interpreted as Markdown by Blackfriday. Backticks will make sure the inner content is not translated as Markdown to HTML, e.g., `$$x *y* z$$` will be converted to <code>$$x *y* z$$</code>. Without the backticks, it will be converted to $$x <em>y</em> z$$, which is not a valid LaTeX math expression for MathJax. Similar issues can arise when you have other special characters like underscores in your math expressions.]

The main disadvantages of rendering .Rmd to .html are:

  1. You may sacrifice some speed in rendering the website, but this may not be noticeable due to a caching mechanism in blogdown (more on this in Section \@ref(local-preview)). Hugo is very fast when processing plain Markdown files, and typically it should take less than one second to render a few hundred posts.

  2. You will have some intermediate HTML files in the source directory of your website, because blogdown has to call rmarkdown to pre-render *.Rmd files into *.html. You will also have intermediate folders for figures (*_files/) and cache (*_cache/) if you have plot output in R code chunks or have enabled knitr's caching. Unless you care a lot about the "cleanness" of the source repository of your website (especially when you use a version control tool like GIT), these intermediate files should not matter.

There are two major limitations of rendering .Rmd to .md (or .Rmarkdown to .markdown):

The main advantage of rendering posts to Markdown instead of HTML is that the output files are cleaner because they are Markdown files (by comparison, HTML files often contain a lot of HTML tags, which are hard for humans to read). It can be easier for you to read the output of your posts without looking at the actual web pages rendered. This can be particularly helpful when reviewing GitHub pull requests. Note that numbered tables, figures, equations, and theorems are also supported. You cannot directly use Markdown syntax in table or figure captions, but you can use text references as a workaround (see bookdown's documentation).

Customize the R Markdown output format

For any R Markdown documents (not specific to blogdown), you have to specify an output format. There are many possible output formats in the rmarkdown package (such as html_document and pdf_document) and other extension packages (such as tufte::tufte_html and bookdown::gitbook). Of course, the output format for websites should be HTML. We have provided an output format function blogdown::html_page in blogdown, and all R Markdown files are rendered using this format. It is based on the output format bookdown::html_document2, which means it has inherited a lot of features from bookdown in addition to features in Pandoc. For example, you can number and cross-reference math equations, figures, tables, and theorems, etc. See Chapter 2 of the bookdown book [@xie2016] for more details on the syntax.

Note that the output format bookdown::html_document2 in turn inherits from rmarkdown::html_document, so you need to see the help page ?rmarkdown::html_document for all possible options for the format blogdown::html_page. If you want to change the default values of the options of this output format, you can add an output field to your YAML metadata. For example, we can add a table of contents to a page, set the figure width to be 6 inches, and use the svg device for plots by setting these options in YAML:

---
title: "My Awesome Post"
author: "John Doe"
date: "2017-02-14"
output:
  blogdown::html_page:
    toc: true
    fig_width: 6
    dev: "svg"
---

To set options for blogdown::html_page() globally (i.e., apply certain options to all Rmd files), you can create a _output.yml file under the root directory of your website. This YAML file should contain the output format directly (do not put the output format under the output option), e.g.,

blogdown::html_page:
  toc: true
  fig_width: 6
  dev: "svg"

At the moment, not all features of rmarkdown::html_document are supported in blogdown, such as df_print, code_folding, code_download, and so on.

If your code chunk has graphics output, we recommend that you avoid special characters like spaces in the chunk label. Ideally, you should only use alphanumeric characters and dashes, e.g., ```r instead of ```r.

It is not recommended to change the knitr chunk options fig.path or cache.path in R Markdown. The default values of these options work best with blogdown. Please read Section \@ref(dep-path) to know the technical reasons if you prefer.

If you are working on an R Markdown post, but do not want blogdown to compile it, you can temporarily change its filename extension from .Rmd to another unknown extension such as .Rmkd.

Other themes

In Hugo, themes\index{Themes} control the entire appearance and functionality of your site. A Hugo theme is made with the following elements:

  1. Configuration files. This may be a single config.yaml or config.toml file in the root of your website project. Some themes also use a configuration directory, located in config/_default/. Read more about these files in Chapter \@ref(configuration).

  2. Layout files, located for example in themes/hugo-lithium/layouts/. Hugo is a templating system, so layout files are *.html files, with a specific file and naming structure. Read more about these files in Section \@ref(templates).

  3. Style asset files like fonts and CSS.

  4. HTML dependencies like JavaScript files.

All of these files are contained in the themes/ folder, and are kept separate from your website content/. However, all Hugo themes rely on specific content/ and YAML frontmatter, so do not be fooled into thinking that themes and content are not dependent on each other---they are! In this section, we provide some opinionated advice on choosing themes, as well as recommended workflows for working with Hugo themes using blogdown.

Choosing themes

If you care a lot about the appearance of your website, you will probably spend quite a bit of time in the beginning looking for a Hugo theme that you like from the collection listed at https://themes.gohugo.io. Please note that not all themes have been tested with blogdown. If you find a certain theme does not work well with blogdown, you may report to https://github.com/rstudio/blogdown/issues, and we will try to investigate the reason, but it can be time-consuming to learn and understand how a new theme works, so we recommend that you learn more about Hugo by yourself before asking, and we also encourage users to help each other there.

There are now about 400 Hugo themes to choose from. To save you some time, we list a few themes below that match our taste:

If you do not understand HTML, CSS, or JavaScript, and have no experience with Hugo themes or templates, it may take you about 10 minutes to get started with your new website, since you have to accept everything you are given (such as the default theme); if you do have the knowledge and experience (and desire to highly customize your site), it may take you several days to get started. Hugo is really powerful. Be cautious with power.

Another thing to keep in mind is that the more effort you make in a complicated theme, the more difficult it is to switch to other themes in the future, because you may have customized a lot of things that are not straightforward to port to another theme. So please ask yourself seriously, "Do I like this fancy theme so much that I will definitely not change it in the next couple of years?"

If you choose to dig a rather deep hole, someday you will have no choice but keep on digging, even with tears.

--- Liyun Chen^[Translated from her Chinese Weibo.]

New site, new theme

To use a Hugo theme other than hugo-lithium with a new site (which we showed in Section \@ref(a-quick-example)), we recommend the following workflow:

  1. Carefully pick a theme at https://themes.gohugo.io, and find the link to its GitHub repository,^[For most themes, you can find this by navigating to the theme of your choice from http://themes.gohugo.io and then clicking on "Download."] which is of the form https://github.com/user/repo. For example, the source of the Hugo theme Anatole is located at https://github.com/lxndrblz/anatole.

  2. Create a new project in RStudio (File -> New Project -> New Directory -> Website using blogdown) (see Figures \@ref(fig:new-project) and \@ref(fig:blogdown-project)).

  3. In the "Hugo theme" field, enter the user/repo from the link in Step 1. Click "Create Project".

    Alternatively, in the R console, you may type blogdown::new_site(theme = 'user/repo'):

    ```r

    for example, create a new site with the anatole theme

    blogdown::new_site(theme = 'lxndrblz/anatole') ```

  4. Play with the new site for a while and if you do not like it, you can repeat the above steps, otherwise edit the options in the configuration file (config.yaml or config.toml). If you do not understand certain options, go to the documentation of the theme, which is often the README page of the GitHub repository. Not all options have to be changed.

Existing site, new theme

Generally, we do not advise you to switch themes, as each Hugo theme depends on different variables that you provide in the theme-specific configuration file (config.yaml or config.toml) and in the YAML of the content/ files. Example sites are often provided for individual themes, so we recommend using blogdown::new_site(), then editing the provided example site as a starting point. However, if you do want to test a different Hugo theme with an existing site, you can start with the following workflow:

  1. In the R console, install the theme via\index{blogdown::install_theme()} blogdown::install_theme().

    r blogdown::install_theme(theme = 'lxndrblz/anatole')

  2. Manually move the configuration file (config.yaml or config.toml) from the themes/theme-name/exampleSite/ directory to the root directory of your website to match the newly installed theme.

  3. Carefully inspect the differences between your new theme's exampleSite and the files inside your content/ folder. A theme's exampleSite content is tailored to a specific theme, so changing themes without changing your content/ is a bit like wearing someone else's clothes---they just may not fit right.

Existing site, update theme

Updating Hugo theme files is not for the faint of heart, and we also do not recommend doing this unless you must. We also generally recommend you only do this when you integrate GIT and GitHub for version control, and that you attempt to update your theme in a branch first.

The main reason this is difficult is that Hugo theme files can require changes in your website configuration file (config.yaml or config.toml) and in the YAML of individual content files, depending on the extent of the theme update. So updating a theme can be quite a hassle.

Why do theme developers update their themes? Three reasons. One, Hugo changes. As a result, Hugo theme developers must change their themes to keep up with deprecated Hugo functions. Two, Hugo theme developers fix their themes when bugs are reported. Three, popular Hugo themes often field lots of feature requests, and some theme developers are responsive to adding new features.

If you find yourself needing to update your theme, you may do the following:

blogdown::install_theme(theme = 'lxndrblz/anatole', force = TRUE)

Then slowly work through what changed in the site configuration files and the content/ frontmatter (YAML metadata) by comparing the updated theme's exampleSite. As stated earlier, we recommend doing this work in a different branch (i.e., not main) before merging.

A recommended workflow {#workflow}

There are a lot of ways to start building a website and deploy it. Because of the sheer number of technologies that you need to learn to fully understand how a website works, we'd like to recommend one workflow to beginners, so that hopefully they do not need to digest the rest of this book. This is definitely not the most optimal workflow, but requires you to know the fewest technical details.

To start a new website:

  1. Carefully pick a theme at https://themes.gohugo.io, and find the link to its GitHub repository, which is of the form https://github.com/user/repo.

  2. Create a new project in RStudio, and type the code blogdown::new_site(theme = 'user/repo') in the R console, where user/repo is from the link in Step 1.

  3. Play with the new site for a while and if you do not like it, you can repeat the above steps, otherwise edit the options in config.toml. If you do not understand certain options, go to the documentation of the theme, which is often the README page of the GitHub repository. Not all options have to be changed.

To edit a website:

  1. Click the RStudio addin "Serve Site" to preview the site in RStudio Viewer. This only needs to be done once every time you open the RStudio project or restart your R session. Do not click the Knit button on the RStudio toolbar.

  2. Use the "New Post" addin to create a new post or page, then start writing the content.

  3. Use the "Update Metadata" addin to modify the YAML metadata if necessary.

To publish a website, see Section \@ref(a-quick-deploy).



rstudio/blogdown documentation built on Feb. 5, 2024, 10:09 p.m.