This tutorial details how to set up a blog using Hugo, intall the PaperMod theme, and host it all on GitHub Pages (for free!). This is how I set up this blog you’re reading.
Outline
- Site is built using Hugo
- Uses PaperMod theme
- Deployed to GitHub Pages
Steps
1. Install Hugo
If you’re on macOS, and have homebrew installed, in your terminal:
brew install hugo
For other OSes, and detailed install instructions see here
2. Create new site
Navigate to the folder where you will want the project to reside. The following command will create the folder for the project, and initiate it with the base files:
hugo new site my-hugo-blog
3. Install PaperMod theme
Navigate into the folder for the site you just created, and then clone the PaperMod Theme into your project
cd my-hugo-blog
git clone https://github.com/adityatelange/hugo-PaperMod themes/PaperMod --depth=1
now get rid of the default config.toml, and create an empty config.yml. YAML is much nicer to read and work with IMO.
rm config.toml
touch config.yml
Copy-paste the following settings into config.yml
(adapted from the PaperMod example site)
baseURL: https://entra.ca
languageCode: "en-us"
title: My Blog
paginate: 5
theme: PaperMod
enableRobotsTXT: true
buildDrafts: false
buildFuture: false
buildExpired: false
minify:
disableXML: true
minifyOutput: true
params:
env: production # to enable google analytics, opengraph, twitter-cards and schema.
title: My Blog
description: "Example website, built on Hugo."
keywords: [Hugo, Blog]
author: Joe Bloggs
# author: ["Me", "You"] # multiple authors
images: ["<link or path of image for opengraph, twitter-cards>"]
DateFormat: "January 2, 2006"
defaultTheme: dark # dark, light, auto
disableThemeToggle: false
ShowReadingTime: true
ShowShareButtons: true
ShowPostNavLinks: true
ShowBreadCrumbs: false
ShowCodeCopyButtons: false
ShowWordCount: true
ShowRssButtonInSectionTermList: true
UseHugoToc: true
disableSpecial1stPost: false
disableScrollToTop: false
comments: false
hidemeta: false
hideSummary: false
showtoc: false
tocopen: false
assets:
# disableHLJS: true # to disable highlight.js
# disableFingerprinting: true
favicon: "<link / abs url>"
favicon16x16: "<link / abs url>"
favicon32x32: "<link / abs url>"
apple_touch_icon: "<link / abs url>"
safari_pinned_tab: "<link / abs url>"
label:
text: "entra.ca"
icon: /apple-touch-icon.png
iconHeight: 35
# profile-mode
profileMode:
enabled: false # needs to be explicitly set
title: Example Blog Site
subtitle: "This is subtitle"
imageUrl: "<img location>"
imageWidth: 120
imageHeight: 120
imageTitle: my image
buttons:
- name: Posts
url: posts
- name: Tags
url: tags
# home-info mode
homeInfoParams:
Title: "Hi there \U0001F44B"
Content: Welcome to my blog
socialIcons:
- name: linkedin
url: "https://www.linkedin.com/"
- name: twitter
url: "https://www.twitter.com/"
- name: stackoverflow
url: "https://stackoverflow.com"
- name: github
url: "https://github.com/"
analytics:
google:
SiteVerificationTag: "XYZabc"
bing:
SiteVerificationTag: "XYZabc"
yandex:
SiteVerificationTag: "XYZabc"
cover:
hidden: true # hide everywhere but not in structured data
hiddenInList: true # hide on list pages and home
hiddenInSingle: true # hide on single page
#editPost:
# URL: "https://github.com/<path_to_repo>/content"
# Text: "Suggest Changes" # edit text
# appendFilePath: true # to append file path to Edit link
# for search
# https://fusejs.io/api/options.html
fuseOpts:
isCaseSensitive: false
shouldSort: true
location: 0
distance: 1000
threshold: 0.4
minMatchCharLength: 0
keys: ["title", "permalink", "summary", "content"]
menu:
main:
- name: Home
identifier: home
url: /
weight: 1
- name: Blog
identifier: blog
url: blog/
weight: 2
#- identifier: projects
# name: Projects
#url: projects/
# weight: 3
#- name: Services
# identifier: hiring
# name: Services
# url: services/
# weight: 4
# Read: https://github.com/adityatelange/hugo-PaperMod/wiki/FAQs#using-hugos-syntax-highlighter-chroma
pygmentsUseClasses: true
markup:
highlight:
noClasses: false
# anchorLineNos: true
# codeFences: true
# guessSyntax: true
# lineNos: true
# style: monokai
You’ll definitely want to adjust the settings in config.yml
, you can do that now or later.
If you had any troubles, there are detailed instruction for installing the PaperMod theme here.
4. Create a blog post
You can author content in Hugo using Markdown. Navigate to the /content
folder, create a new folder for your blog post, and create a new .md
file
cd content
mkdir blog
cd blog
touch first-post.md
Now in your text editor, open first-post.md
and add the following:
---
title: "First Post"
date: 2023-03-15T22:57:04+05:30
draft: false
category: Blogging
slug: first-post
summary:
First Blog post
description:
First Blog post
---
This is metadata that Hugo will use to build your blog. The most important items are title
, and slug
. The slug
will be used to form the URL.
Below the metadata section, you can add some text. For example:
...
description:
First Blog post
---
Hello, world. This is my first blog post!
5. Preview
Now you’re ready to preview! Start up the server from the project root
cd ../..
hugo server
If all goes well, you should be able to see your site at http://localhost:1313/ (or whichever port hugo tells you on the command line that it’s serving from)
You should be able to see your blog post at http://localhost:1313/blog/first-post
One really nice thing about running hugo server
is that it does hot-reloading. This means any time you change a file in your project and save, the server updates the state of the current page to the client using websockets.
Now you might take the time to customize the settings in config.yml
, and honing that perfect blog post. Once you’re ready to deploy, you can proceed to build the static site.
6. Build
Build your static website with this simple command:
hugo
So fast! So easy! This command will build all of your site into the /public
folder. It will now contain all of the static assets that make up your built Hugo website. This is all the stuff that we want to put on the web.
7. Deploy
We want people to be able to read this blog, so it needs to go on the web. We’re going to use GitHub’s free GitHub Pages service to do that. You’ll needa github account.
In GitHub, create a new repository. I’ve been doing this using the GUI on the GitHub website, but the CLI (Command Line Interface) looks nice and would be better suited to a tutorial like this.
Yu can follow these instructions up until the part that says
Congratulations! You’ve successfully created your first repository, and initialized it with a README file.
Now that you’ve set up your repo, go back to your terminal and navigate to the freshly built /public
folder. You’re going to set this up to be tracked using git.
cd public
git init
git add .
git commit -m "My first commit"
git remote add origin git@github.com:my-user-name/hello-world.git
git pull origin master # this should cause the README.txt and anything else that github just created to merge in
git push origin master
Great! Your code is up on github. Now we just need to set it up to deploy to GitHub Pages!
Next you need to adjust the settings on your GitHub repo to publish your project to GitHub Pages.
Follow these instructions
Sometimes it takes a few minutes to deploy. Your site will be visible at on the github domain, at a URL similar to https://my-username.github.io/hello-world
However, with GitHub pages, you can use your own domain. This is what I’m doing with my entra.ca
domain. Even better!
Instructions for using a custom domain here
8. Profit 📈
Congratulations, you now have your very own blog! Now you can watch the profits pour in.
9. Relax
You deserve a break. Why not grab a glass of lemonade and bask in the glory?
Ahh.. that was nice.
Next time you want to post a blog, all you have to do is write another .md
and place it in the /blog
folder, then do the following from the root of your project
hugo # rebuild the static site, including your latest post
cd public
git add .
git commit -m "posting a blog"
git push origin master # deploy!
10. Extra
Before adding this Hugo blog, my webpage was just a simple html single page portfolio site. I wanted to keep that in place as the homepage, and simply tack on the blog to it.
The way I achieved this was to put my old single pager in /layouts/index.html
. Hugo simply uses this file as the template for the homepage when you go to https://entra.ca.
I had to hack a replica of the top menu directly into that template, but it does the trick well enough for now. I plan to make it behave more like a normal Hugo template down the road, by including the menu properly from the Hugo source.