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

3.2 GitHub Pages

GitHub Pages (https://pages.github.com) is a very popular way to host static websites (especially those built with Jekyll), but its advantages are not obvious or appealing compared to Netlify. We recommend that you consider Netlify + Hugo due to these reasons:

  • Redirecting URLs is awkward with GitHub Pages but much more straightforward with Netlify.31 This is important especially when you have an old website that you want to migrate to Hugo; some links may be broken, in which case you can easily redirect them with Netlify.

  • One of the best features of Netlify that is not available with GitHub Pages is that Netlify can generate a unique website for preview when a GitHub pull request is submitted to your GitHub repository. This is extremely useful when someone else (or even yourself) proposes changes to your website, since you have a chance to see what the website would look like before you merge the pull request.

Basically, Netlify can do everything that GitHub Pages can, but there is still one little missing feature, which is closely tied to GitHub itself, which is GitHub Project Pages. This feature allows you to have project websites in separate repositories, e.g., you may have two independent websites https://username.github.io/proj-a/ and https://username.github.io/proj-b/, corresponding to GitHub repositories username/proj-a and username/proj-b, respectively. However, since you can connect any GitHub repositories with Netlify, and each repository can be associated with a domain or subdomain name, you may replace GitHub Project Pages with different subdomains like proj-a.netlify.com and proj-b.netlify.com. The actual limitation is that you cannot use subpaths in the URL but you can use any (sub)domain names.

Although GitHub does not officially support Hugo (only Jekyll is supported), you can actually publish any static HTML files on GitHub Pages, even if they are not built with Jekyll. The first requirement for using GitHub Pages is that you have to create a GitHub repository named username.github.io under your account (replace username with your actual GitHub username), and what’s left is to push your website files to this repository. The comprehensive documentation of GitHub Pages is at https://pages.github.com, and please ignore anything related to Jekyll there unless you actually use Jekyll instead of Hugo. To make sure GitHub does not rebuild your website using Jekyll and just publish whatever files you push to the repository, you need to create a (hidden) file named .nojekyll in the repository.32 GitHub offers a free subdomain username.github.io, and you can use your own domain name by configuring its A or CNAME records to point it to GitHub Pages (consult the GitHub Pages documentation for instructions).

Your public/ directory should be the GIT repository. You have two possible choices for setting up this repository locally. The first choice is to follow the default structure of a Hugo website like the diagram below, and initialize the GIT repository under the public/ directory:

source/

├── config.toml
├── content/
├── themes/
├── ...
└── public/
    |
    ├── .git/
    ├── .nojekyll
    ├── index.html
    ├── about/
    └── ...

If you know how to use the command line, change the working directory to public/, and initialize the GIT repository there:

cd public
git init
git remote add origin https://github.com/username/username.github.io

The other choice is to clone the GitHub repository you created to the same directory as your website source:

git clone https://github.com/username/username.github.io

And the structure looks like this:

source/

├── config.toml
├── content/
├── themes/
└── ...

username.github.io/

├── .git/
├── .nojekyll
├── index.html
├── about/
└── ...

The source directory and the username.github.io directory are under the same parent directory. In this case, you need to set the option publishDir = "../username.github.io" in source/config.toml.


  1. GitHub Pages uses a Jekyll plugin to write an HTTP-REFRESH meta tag to redirect pages, and Netlify can do pattern-based 301 or 302 redirects, which can notify search engines that certain pages have been moved (permanently or temporarily).↩︎

  2. You may use the R function file.create('.nojekyll') to create this file if you do not know how to do this.↩︎