A note from the authors: Some of the information and instructions in this book are now out of date because of changes to Hugo and the blogdown package. If you have suggestions for improving this book, please file an issue in our GitHub repository. Thanks for your patience while we work to update the book, and please stay tuned for the revised version!

In the meantime, you can find an introduction to the changes and new features in the v1.0 release blog post and this "Up & running with blogdown in 2021" blog post.

— Yihui, Amber, & Alison

1.2 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.

1.2.1 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.3

We also assume that you have followed the installation instructions in Section 1.1.

1.2.2 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 1.1 and 1.2).

Create a new website project in RStudio.

FIGURE 1.1: Create a new website project in RStudio.

Create a website project based on blogdown.

FIGURE 1.2: Create a website project based on blogdown.

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:

  • config.yaml: Hugo and theme configuration file.
  • .Rprofile: File to set up your blogdown options.
  • netlify.toml: File to set up your Netlify options.
  • content/: Website source files to edit and add, such as blog posts.
  • themes/: Hugo theme assets like HTML layout files and CSS, etc. Do not edit!

After all this, your new site is ready!

1.2.3 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 1.3).

Use the blogdown addin to serve the site.

FIGURE 1.3: Use the blogdown addin to serve the site.

Then you should see something that looks like Figure 1.4.

Serving the site in RStudio.

FIGURE 1.4: Serving the site in RStudio.

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 1.5.

The homepage of the default new site.

FIGURE 1.5: The homepage of the default new site.

Let’s introduce an important and helpful technology that you just used: LiveReload. Serving your site uses LiveReload, which means your website4 will be automatically rebuilt and reloaded in your web browser5 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() and Hugo, and you will only need to use it once per work session.

1.2.4 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}
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 echo=FALSE}
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 1.6.

Adding new R code to an .Rmd post.

FIGURE 1.6: Adding new R code to an .Rmd post.

1.2.5 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

1.2.6 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.

1.2.7 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 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.

1.2.8 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 3 if you are not familiar with deploying websites.

We will also show how to use other themes in Section 1.7. 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.


  1. 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/.↩︎

  2. 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 3 for details.↩︎

  3. You can also think of the RStudio Viewer as a web browser.↩︎