Looking back at my first post in Bahasa Indonesia, I said that I was using Hugo to build this blog. So in this post I will share my documentation about it here.
Below are the main goals of this post:
- Installing Hugo
- Creating a Site with Hugo
- Deploying the site using GitHub pages
There are some prerequisites needed to accomplish these goals:
- A GitHub account
- Familiarity with CLI commands and basic Git workflow
- Git Bash for Windows users
If you don’t meet any of these prerequisites, just follow along!
First thing first, we’ll need the Hugo executable binary, which you can grab it here.
Pick your Hugo version according to what OS you’re running. There is also the extended version, which you should use if you’re building your own theme or picking a theme that uses Sass/SCSS.
Once the download is completed, just extract it somewhere on your system.
$ ls -l total 47488 -rw-r--r-- 1 Fahmi FJ 197121 11357 Mar 22 00:17 LICENSE -rw-r--r-- 1 Fahmi FJ 197121 12345 Mar 22 00:17 README.md -rwxr-xr-x 1 Fahmi FJ 197121 48599040 Mar 22 01:04 hugo.exe
Let’s see if the executable works by checking its version:
$ hugo.exe version hugo v0.82.0-9D960784+extended windows/amd64 BuildDate=2021-03-21T17:28:04Z VendorInfo=gohugoio
At this time, Hugo’s binary is not available in the system-wide, in other words it’s couldn’t be called outside the current directory where you extracted it. So we’ll add the folder path where the binary lives on to what is known as PATH variable.
System-wide in Windows
For Windows users, let’s create a folder called
Once the folder is created, move your Hugo binary into it.
C:\>dir bin Volume in drive C is Windows Volume Serial Number is AC06-7D93 Directory of C:\bin 13/06/2021 08:07 <DIR> . 13/06/2021 08:07 <DIR> .. 22/03/2021 01:04 48.599.040 hugo.exe 1 File(s) 48.599.040 bytes 2 Dir(s) 57.909.837.824 bytes free
After that, hit
Win + R on your keyboard, type the following command and hit enter:
You should see a window titled “Environment Variables”. Now we’re going to edit the
Path variable there.
On the edit window, add a new path and type
After that, just hit all the OK button.
Then re-open your Windows terminal and run
hugo version. If it returns the same output as previous one, then go to the next section.
System-wide in Linux
I know those who use Linux probably already know how to 😁.
For Linux users, let’s create a folder called
$ mkdir -p ~/.local/bin
Then move your Hugo binary into the newly created
$ mv /previous/path/of/hugo ~/.local/bin/hugo
Next, open your
.zshrc file which is located at
/home/username/.(zsh|bash)rc with your favorite text editor such as vim, and then simply add these lines at the top of your
PATH_HUGO='/home/username/.local/bin' export PATH=$PATH_HUGO:$PATH
Re-open your terminal and run
hugo version from any directory and see if it’s returns the version.
Creating First Site
We can create a site in anywhere by issuing the command below.
$ hugo new site [site-name]
I recommend you to create a site in a specific folder such as
workspaceor something like
For now, let’s call our new site
$ hugo new site my-blog Congratulations! Your new Hugo site is created in C:\Users\fahmi\Desktop\test\my-blog. Just a few more steps and you're ready to go: 1. Download a theme into the same-named folder. Choose a theme from https://themes.gohugo.io/ or create your own with the "hugo new theme <THEMENAME>" command. 2. Perhaps you want to add some content. You can add single files with "hugo new <SECTIONNAME>\<FILENAME>.<FORMAT>". 3. Start the built-in live server via "hugo server". Visit https://gohugo.io/ for quickstart guide and full documentation.
We see that Hugo creates a new folder called
C:\Users\fahmi\Desktop\test\my-blog, and this
my-blog has the following directory structure:
my-blog ├── archetypes │ └── default.md ├── config.toml ├── content ├── data ├── layouts ├── static └── themes
We can host that site locally by typing
hugo server within
my-blog directory. By default, the site is hosted at
$ cd my-blog $ hugo server
For now, it’ll be empty because we haven’t added any content yet.
For site configuration (
config.toml), I’ll recommend you to use YAML format over TOML . So if you want to change the configuration format to YAML, just delete the previous
my-blog and recreate it with the following command:
$ rm ./my-blog/ -rfi # becareful with this or just delete it from explorer $ hugo new site my-blog -f yml
Using a Theme
To add the PaperMod theme by cloning it into the
$ git clone https://github.com/adityatelange/hugo-PaperMod themes/PaperMod --depth=1
Then replace/overwrite our
config.yml with this one, and modify the value of
theme to these:
baseURL: "" theme: PaperMod
Let’s see how it looks like by visiting
http://localhost:1313 on the browser after we run this command.
$ hugo server
Creating First Post
We can create a new post by issuing the following command:
$ hugo new post/new-post.md
You can edit
new-post.md after that, the file should be under
$ ls -l my-blog/content/post/ total 1 -rw-r--r-- 1 Fahmi FJ 197121 70 Jun 13 09:34 my-post.md
To see your post in the site, change the value
--- title: "My Post" date: 2021-06-13T09:34:43+07:00 draft: false --- My first post
It should be on your site now.
Publish Your Site on GitHub
One thing you need to know is that when you run
$ hugo server, Hugo generates all the site resources (html, images, etc.) and serves them directly from memory. But, if you just run
$ hugo, Hugo generates all the site resources under the
public folder (
my-blog ├── archetypes │ └── default.md ├── config.yaml ├── content ├── data ├── layouts ├── static └── themes
These files in the
public folder are the files that we are going to publish on GitHub. We can simply upload all the files in the
public folder into a GitHub repository.
But, before that, you have to change your site’s base URL in
For example, my username is
fahmifj , so my config would be:
Once you done with the config, type
hugo within the root directory of your site to re-generate all the site resources.
$ hugo Start building sites … | EN | FR | FA -------------------+----+----+----- Pages | 14 | 10 | 10 Paginator pages | 0 | 0 | 0 Non-page files | 0 | 0 | 0 Static files | 0 | 0 | 0 Processed images | 0 | 0 | 0 Aliases | 3 | 0 | 1 Sitemaps | 2 | 1 | 1 Cleaned | 0 | 0 | 0 Total in 147 ms
Now, let’s navigate to Github and create a new repository called
my-blog. Once the repo is created, click on Upload an existing file.
Then simply drag and drop all the files from the
my-blog/public folder there.
Once all the files are uploaded, commit the changes. I’ll just leave the default commit message.
After that, let’s head to the repository settings and find the Github Pages menu or visit https://github.com/your-username/my-blog/settings/pages.
Since we’ll host this whole repository using GitHub pages, we need to define our “Source” which is the root directory of main branch, and then click on the Save button.
Once you done with that, navigate to
https://yourusername.github.io/my-blog, and you should see your site there.
If you don’t see it or the page returns a 404 error, then just wait for a few minutes more because our site needs to be cached by the Internet.
Finally, we’re going to (semi) automate the deployment process using a bash script.
Let’s go back to the directory of
my-blog and then initialize
public folder as a git repository. We’ll also add the
public folder as a submodule.
$ cd public $ git init $ git remote add origin https://github.com/your-username/my-blog.git
Now let’s create a deployment script at the site root directory and name it as
#!/bin/bash echo -e "\033[0;32mDeploying blog to GitHub...\033[0m" # Clean public folder hugo --cleanDestinationDir # Go to to public folder cd public/ # Add untracked files, hide output git add -A > /dev/null # Generate a fixed commit message with date and time msg="[`date "+%R %d-%h-%Y"]` Site update" # Check for additional commit message read -p "Add commit message: " add_msg if [ "$add_msg" != "" ] then msg="$msg - $add_msg" fi git commit -m "$msg" # Deploy git push -u origin main # Go back to the root directory cd ../
You can run the script on Windows if you have Git Bash installed or WSL.
Let’s create another post to test the deployment script.
$ hugo new post/second-post.md $ echo 'This is second post' >> content/post/second-post.md
Don’t forget to change the value of
false, here is a small trick with
$ sed -i 's/draft: false/draft: true/g' content/post/second-post.md
Now we can run the script after giving it execute permission.
$ chmod +x deploy.sh $ ./deploy.sh Deploying blog to GitHub... Start building sites … | EN | FR | FA -------------------+----+----+----- Pages | 15 | 10 | 10 Paginator pages | 0 | 0 | 0 Non-page files | 0 | 0 | 0 Static files | 0 | 0 | 0 Processed images | 0 | 0 | 0 Aliases | 3 | 0 | 1 Sitemaps | 2 | 1 | 1 Cleaned | 0 | 0 | 0 Total in 155 ms Add commit message: [main af4c483] [11:00 13-Jun-2021] Site update 9 files changed, 459 insertions(+), 8 deletions(-) create mode 100644 post/second-post/index.html Enumerating objects: 27, done. Counting objects: 100% (27/27), done. Delta compression using up to 8 threads Compressing objects: 100% (13/13), done. Writing objects: 100% (15/15), 3.54 KiB | 1.77 MiB/s, done. Total 15 (delta 9), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (9/9), completed with 7 local objects. To https://github.com/fahmifj/my-blog.git f7141a3..af4c483 main -> main Branch 'main' set up to track remote branch 'main' from 'origin'.
And the repo should be updated.
This is how I deployed my site on my first try. However, this is an inefficient method because it wastes your bandwidth. Therefore, in the next post, let’s employ GitHub action 😼.
[Updated on 2021-11-01]