Featured image of post Setting up Hugo static blog page

Setting up Hugo static blog page

Problem setting

When I first tried to build up a blog, I have been thinking about renting a VPS and running a Wordpress instance on it. This is why you have seen the previous blog. But:

  • VPS costs you, sometimes payment is done annually in one installment.
  • In terms of a blog, dynamic nature of Wordpress is an overkill.
  • Have to setup TLS termination proxy, Wordpress and a MySQL instance. Heavy :(

I have seen some of my friends spinning up their blog using Hugo. With the static page hosting service (free!) by Cloudflare Pages, I have decided to give it a try.

In this blog, I’ll mainly talk about the subtle problems I have faced in these sessions besides trivial documentation.

  1. How to setup a Hugo blog
  2. Using the Stack hugo theme
  3. Deploying to Cloudflare Pages
  4. Setting up Front Matter CMS (Content Management System) for easy content creation in vscode

1. Setting up Hugo

Hugo is a static site generator written in Go that is blazingly fast. To start a new hugo project, simply follow the quickstart guide.

archetypes front matter template

Hugo uses front matter, a “preamble” in the markdown file to store metadata and control the behavior of the content. In fact here is the front matter of this blog:

---
title: Setting up Hugo static blog page
description: ""
date: 2024-08-23T14:15:58.493Z
preview: "" # This is for `Front Matter CMS`
draft: false
tags: []
categories: []
image: "" # This is for `Stack` theme, the header you have seen in this post.
slug: setting-up-hugo-static-blog-page
---

One (probably annoying thing) about Hugo is that it can use TOML, YAML or JSON for front matter. I like yaml but the default generated content with hugo new post/your-post.md is TOML. In addition, sometimes you do want the autogenerated files have different front matter according to the content type.

The solution is to open the archetypes folder and edit the default.md file, or create new ones such as post.md file. Hugo will match the templates according to the type, e.g. hugo new post/your-post.md will use the post.md template. Check the matching rules.

2. Using the Stack hugo theme

If I haven’t changed the theme after I have written this blog🤔, I am using the Stack theme. More than grateful for CaiJimmy for designing this elegant theme. It also has a nice documentation.

For those that would like to set up the frames quickly, here are some steps:

Setting up sidebar

  • Go to the theme folder of the Stack theme (should be something like themes/hugo-theme-stack), find the config.yaml.
  • Find the params.sidebar section and fill in the details.

Setting up main menu and widgets

Stack provides menu items on the left and interesting widgets on the right side of the page. To setup those widgets you have to follow some steps:

  1. Create those pages under the content/page folder. The theme relies on those pages to build the widgets.

content/page/archives/index.md

---
title: "Archives"
layout: "archives"
slug: "archives"
menu:
    main:
        params: 
            icon: archives
---

content/page/about/links.md

---
title: Links
links:
  <!-- This is a sample links page to Github. -->
  - title: GitHub
    description: GitHub is the world's largest software development platform.
    website: https://github.com
    image: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png
menu:
    main: 
        params:
            icon: link

comments: false
---

<!-- To use this feature, add `links` section to frontmatter.
`image` field accepts both local and external images. -->

content/page/about/search.md

---
title: "Search"
slug: "search"
layout: "search"
outputs:
    - html
    - json
menu:
    main:
        params: 
            icon: search
---

Notes

  • You can also add the weight parameter to menu.main.params to change the order of the main menu items.
  • The icon parameter refers to the SVGs in assets/icons folder in your theme folder. For example, icon: archives refers to assets/icons/archives.svg.
  1. After the creation of those pages, go to the config.yaml file in your theme folder. We first customize the left menu:
# Custom menu configurations
# The `icon` refers to the SVGs in `assets/icons` folder.
# `Stack` uses icons from tabler.io (https://tabler.io/icons), 
# which you can download for customization.
menu:
    main:
        - identifier: home
          name: Home
          url: /
          weight: 1
          params:
            icon: home
            newTab: false
    # Social menu doesn't have text, just a list of icons.
    social:
        - identifier: github
          name: GitHub
          url: <your-github-link>
          params:
            icon: brand-github
            newTab: true
params:
    widgets:
        homepage: 
            - type: "search"
            - type: "archives"
              params:
                limit: 5
            - type: "categories"
              params:
                    limit: 10
        page:
            - type: "toc"

This enables the menu items and widgets.

Fix the code block glitch

A glitch in the current version (Stack v3.26.0) is that the code block has a mysterious black background. This should be a temporary issue but here is the (official) fix:

  • Go to hugo.yaml (or hugo.toml, if you haven’t changed the configuration file format) in the project root.
  • Add:
markup:
  highlight:
   noClasses: false

3. Deploying to Cloudflare Pages

In normal circumstances deploying this stack to Cloudflare should be a smooth process.

The Stack v3.26.0 however breaks the Cloudflare automatic page building process, which is probably caused by using an old image version of Hugo. To fix this, in your page build configuration, add the environment variable:

# Change to the newest or compatible Hugo version at your reading time.
HUGO_VERSION=v0.133.0

and it should fix the issue.

4. Setting up Front Matter CMS

Front matter is a vscode extension that runs locally and manages your contents and does SEO. It has high flexibility but setting it up was a nightmare for me (due to my lack of coding skills 😭). Anyways, I provide some key setups aside from the general guidance Front Matter CMS provides, which itself is nice👍.

Markdown front matter template and page bundle support

One thing that you have to notice is that Front Matter does not respect the settings you provided in the archetypes folder. It uses its own template located inside the frontmatter.json generated.

Here is the modification I provide, with three augmentations:

  • Enable page bundle support.
    • Page bundle is a way to organize your resources and an index.md in one folder. If you do not know what a page bundle is, check the Hugo documentation.
  • Added the slug field. Slug is very important in Front Matter since it use it to open the preview (which I cover in later sections).
  • Added the image field, which is used by the Stack theme.

Note

I regard it as a very INELEGANT modification since I directly modify the default profile, which I should create a new post profile or somehow.

But I mainly use CMS for writing posts, so, lazy me 🤷.

"frontMatter.taxonomy.contentTypes": [
    {
      "name": "default",
      // When generating page content, use a page-bundle format.
      "pageBundle": true,
      "fields": [
        // ...
        // This is for the header post image in `Stack` theme.
        {
          "title": "Post image",
          "name": "image",
          "type": "image"
        },
        // This is for automatic slug generation.
        {
          "title": "Slug",
          "name": "slug",
          "type": "slug",
          "editable": true,
          "default": "{{slug}}"
        }
        // ...
      ]
    }
  ],

Preview setup

Front Matter CMS uses the slug of the pages to generate the preview. What it actually does is:

  1. Spins up a local server (you have to click the Start server button.)
  2. Generates a link to the page you are currently working on, using the rules here. In short, <preview host URL>/<frontMatter.preview.pathName>/<slug>.
  3. Open a browser based on the link.

It’s important to know that you have to setup the frontmatter.json correctly to use the preview feature. Also, you have to make sure that the preview pathname is correctly set. If not, it will access <hostname>/<slug> rather than, for example, <hostname>/post/<slug> (let’s assume you host posts under the content/post folder).

The difficulty is really to recognize the aforementioned fact - once you understand it it is not hard at all and it is well documented.

Check the documentation here to modify the generated frontmatter.json by adding previewPath property according to the instructions.

5. Epilogue

Let’s shift away from the technical story and talk about something rather personal.

Sometimes I do think trying new thing is a hard time, but it still provides that dopamine surge that supports you to work until five in the morning. I have had a long chat with one of my friend, on the essence of software engineering (I probably will write a blog afterwards on this topic). What he essentially said is that SWE is an art for solving the problems, and it really depends on your experience to know what is the best solution.

He is right, in my opinion. There are so many awesome tools out there waiting to be explored, although during the exploration I do have to bang my head against the wall just to compensate for my lack of knowledge. Spending for like 12 hrs to just setup a page and spending another 3 hrs to write a blog recording my mistake is “not a good time management”. But I do think it is worth it to left some record here just to make myself setting up the next blog easier. And, if I am lucky enough to have a reader like you🤗, hope this helps.