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
The first file that you may want to look at is the configuration or
config file in your root directory, in which you can set global configurations of your site. It may contain options like the title and description of your site, as well as other global options like links to your social networks, the navigation menu, and the base URL for your website.
When generating your site, Hugo will search for a file called
config.toml first. If it cannot find one, it will continue to search for
config.yaml.16 Since most Hugo themes contain example sites that ship
config.toml files, and the TOML (Tom’s Obvious, Minimal Language) format appears to be more popular in the Hugo community, we will mainly discuss
We recommend that you use the TOML syntax only for the config file (you can also use YAML if you prefer), and use YAML as the data format for the metadata of (R) Markdown pages and posts, because R Markdown and blogdown fully support only YAML.17 If you have a website that has already used TOML, you may use
blogdown::hugo_convert(unsafe = TRUE) to convert TOML data to YAML, but please first make sure you have backed up the website because it will overwrite your Markdown files.
The Hugo documentation does not use TOML or YAML consistently in its examples, which can be confusing. Please pay close attention to the configuration format when copying examples to your own website.
2.2.1 TOML Syntax
If you are not familiar with the TOML Syntax, we will give a brief overview and you may read the full documentation to know the details.
TOML is made up of key-value pairs separated by equal signs:
When you want to edit a configuration in the TOML file, simply change the value. Values that are character strings should be in quotes, whereas Boolean values should be lowercase and bare.
For example, if you want to give your website the title “My Awesome Site,” and use relative URLs instead of the default absolute URLs, you may have the following entries in your
= "My Awesome Site" title = truerelativeURLs
Most of your website’s global variables are entered in the
config.toml file in exactly this manner.
Further into your
config file, you may notice some values in brackets like this:
[social]= "https://github.com/rstudio/blogdown" github = "https://twitter.com/rstudio" twitter
This is a table in the TOML language and Hugo uses them to fill in information on other pages within your site. For instance, the above table will populate the
.Site.Social variable in your site’s templates (more information on this in Section 2.5).
Lastly, you may find some values in double brackets like this:
.main]] [[menu= "Blog" name = "/blog/" url .main]] [[menu= "Categories" name = "/categories/" url .main]] [[menu= "About" name = "/about/" url
In TOML, double brackets are used to indicate an array of tables. Hugo interprets this information as a menu. If the code above was found in a
config.toml file, the resulting website would have links to Blog, Categories, and About pages in the site’s main menu. The location and styling of that menu are specified elsewhere, but the names of each menu’s choices and the links to each section are defined here.
config.toml file is different for each theme. Make sure that when you choose a theme, you read its documentation thoroughly to get an understanding of what each of the configuration options does (more on themes in Section 2.4).
All built-in options that you may set for Hugo are listed at https://gohugo.io/overview/configuration/. You can change any of these options except
contentDir, which is hard-coded to
content in blogdown. Our general recommendation is that you’d better not modify the defaults unless you understand the consequences. We list a few options that may be of interest to you:
baseURL: Normally you have to change the value of this option to the base URL of your website. Some Hugo themes may have it set to
http://www.example.com/in their example sites, but please make sure to replace them with your own URL (see Chapter 3 and Appendix C for more information on publishing websites and obtaining domain names). Note that this option can be a URL with a subpath, if your website is to be published under a subpath of a domain name, e.g.,
enableEmoji: You may set it to
trueso that you can use Emoji emoticons like
permalinks: Rules to generate permanent links of your pages. By default, Hugo uses full filenames under
content/to generate links, e.g.,
content/about.mdwill be rendered to
content/post/2015-07-23-foo.mdwill be rendered to
public/post/2015-07-23-foo/index.html, so the actual links are
/post/2015-07-23-foo/on the website. Although it is not required to set custom rules for permanent links, it is common to see links of the form
/YYYY/mm/dd/post-title/. Hugo allows you to use several pieces of information about a source file to generate a link, such as the date (year, month, and day), title, and filename, etc. The link can be independent of the actual filename. For example, you may ask Hugo to render pages under
content/post/using the date and title for their links:
[permalinks]= "/:year/:month/:day/:title/" post
Personally, I recommend that you use the
:slugvariable18 instead of
[permalinks]= "/:year/:month/:day/:slug/" post
This is because your post title may change, and you probably do not want the link to the post to change, otherwise you have to redirect the old link to the new link, and there will be other types of trouble like Disqus comments. The
:slugvariable falls back to
:titleif a field named
slugis not set in the YAML metadata of the post. You can set a fixed slug so that the link to the post is always fixed and you will have the freedom to update the title of your post.
You may find a list of all possible variables that you can use in the
permalinksoption at https://gohugo.io/extras/permalinks/.
publishDir: The directory under which you want to generate the website.
theme: The directory name of the Hugo theme under
ignoreFiles: A list of filename patterns (regular expressions) for Hugo to ignore certain files when building the site. I recommend that you specify at least these patterns
["\\.Rmd$", "\\.Rmarkdown$", "_cache$"]. You should ignore
.Rmdfiles because Hugo should only recognize their output files (such as
.mdfiles). Directories with the suffix
_cacheshould be ignored because they contain auxiliary files after an
Rmdfile is compiled, which are useless to Hugo.
uglyURLs: By default, Hugo generates “clean” URLs. This may be a little surprising and requires that you understand how URLs work when your browser fetches a page from a server. Basically, Hugo generates
foo.mdby default instead of
foo.html, because the former allows you to visit the page via the clean URL
index.html. Most web servers understand requests like
http://www.example.com/foo/and will present
foo/to you. If you prefer the strict mapping from
*.html, you may enable “ugly” URLs by setting
hasCJKLanguage: If your website is primarily in CJK (Chinese, Korean, and Japanese), I recommend that you set this option to
true, so that Hugo’s automatic summary and word count work better.
Besides the built-in Hugo options, you can set other arbitrary options in
config.toml. For example, it is very common to see an option named
params, which is widely used in many Hugo themes. When you see a variable
.Site.Params.FOO in a Hugo theme, it means an option
FOO that you set under
Frida Gomam with the following config file:
[params]= "Frida Gomam" author = "2006/01/02" dateFormat
The goal of all these options is to avoid hard-coding anything in Hugo themes, so that users can easily edit a single config file to apply the theme to their websites, instead of going through many HTML files and making changes one by one.
Hugo also supports
config.json, but blogdown does not support it, so we do not recommend that you use it.↩︎
TOML has its advantages, but I feel they are not significant in the context of Hugo websites. It is a pain to have to know yet another language, TOML, when YAML stands for “Yet Another Markup Language.” I’m not sure if the XKCD comic applies in this case: https://xkcd.com/927/.↩︎
A slug is simply a character string that you can use to identify a specific post. A slug will not change, even if the title changes. For instance, if you decide to change the title of your post from “I love blogdown” to “Why blogdown is the best package ever,” and you used the post’s title in the URL, your old links will now be broken. If instead, you specified the URL via a slug (something like “blogdown-love”), then you can change the title as many times as you’d like and you will not end up with any broken links.↩︎