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

2.7 Static files

All files under the static/ directory are copied to public/ when Hugo renders a website. This directory is often used to store static web assets like images, CSS, and JavaScript files. For example, an image static/foo/bar.png can be embedded in your post using the Markdown syntax ![](/foo/bar.png).23

Usually a theme has a static/ folder, and you can partially override its files using the same mechanism as overriding layouts/ files, i.e., static/file will override themes/theme-name/static/file. In the XMin theme, I have two CSS files style.css and fonts.css. The former is the main style sheet, and the latter is a quite small file to define typefaces only. You may want to define your own typefaces, and you can only provide a static/css/fonts.css to override the one in the theme, e.g.,

body {
  font-family: "Comic Sans MS", cursive, sans-serif;
}
code {
  font-family: "Courier New", Courier, monospace;
}

To R Markdown users, another important application of the static/ directory is to build Rmd documents with custom output formats, i.e., Rmd documents not using the blogdown::html_page() format (see Section 1.6). For example, you can generate a PDF or presentations from Rmd documents under this directory, so that Hugo will not post-process them but simply copies them to public/ for publishing. To build these Rmd files, you must provide a custom build script R/build.R (see Section D.9). You can write a single line of code in this script:

blogdown::build_dir("static")

The function build_dir() finds all Rmd files under a directory, and calls rmarkdown::render() to build them to the output formats specified in the YAML metadata of the Rmd files. If your Rmd files should not be rendered by a simple rmarkdown::render() call, you are free to provide your own code to render them in R/build.R. There is a built-in caching mechanism in the function build_dir(): an Rmd file will not be compiled if it is older than its output file(s). If you do not want this behavior, you can force all Rmd files to be recompiled every time: build_dir(force = TRUE).

I have provided a minimal example in the GitHub repository yihui/blogdown-static, where you can find two Rmd examples under the static/ directory. One is an HTML5 presentation based on the xaringan package, and the other is a PDF document based on bookdown.

You need to be cautious about arbitrary files under static/, due to Hugo’s overriding mechanism. That is, everything under static/ will be copied to public/. You need to make sure that the files you render under static/ will not conflict with those files automatically generated by Hugo from content/. For example, if you have a source file content/about.md and an Rmd file static/about/index.Rmd at the same time, the HTML output from the latter will overwrite the former (both Hugo and you will generate an output file with the same name public/about/index.html).


  1. The link of the image depends on your baseurl setting in config.toml. If it does not contain a subpath, /foo/bar.png will be the link of the image, otherwise you may have to adjust it, e.g., for baseurl = "http://example.com/subpath/", the link to the image should be /subpath/foo/bar.png.↩︎