There are a total of 104 posts here. | 這裡總共有 104 篇貼文。

ttheng's microblog. | 侃侃而隨想極短文。

Extracting slug from filename in Hugo

TL;DR: Change every instance of :slug in the site configuration file into :slugorcontentbasename. See here for more info.


When building a website using the static site generator Hugo, some Hugo themes, such as Stack and hugo-bearblog (which is the theme used here), by default generate the ‘slug’ portion of the URL of a webpage by extracting and reformatting the title field provided in the front matter of the source Markdown file of the page.

This is because in the site configuration file of a Hugo site with such themes installed, the permalinks key, which determines how the URL looks like, is usually set up as something like this…

permalinks:
    post: /p/:slug/
    page: /:slug/

(The above snippet is obtained from the example site configuration file provided in the GitHub repository of the Stack theme, in YAML format.)

…or this.

[permalinks]
  blog = "/:slug/"

(The above snippet is obtained from the example site configuration file provided in the hugo-bearblog GitHub repository, in TOML format.)

The key here is the use of the token :slug. According to Hugo’s documentation, this token generates the URL ‘slug’ based on the title in front matter, unless a slug entry is provided. If neither is given, Hugo automatically generates one.

For example, if we’re using the (default) hugo-bearblog theme, and the Markdown file of a Hugo webpage in the blog directory looks like this (the front matter is in TOML format):

+++
title = 'My First Post 1'
+++

This is my first post!

Due to the configuration as shown above, the resulting URL of the corresponding webpage may then look like this:

https://example.org/my-first-post-1/

However, this presents a problem when we need to change the title of a webpage multiple times, as doing so will cause the URL of the page to change constantly.

This renders the old versions of the link useless, and makes sharing or publishing the page link a cumbersome task, as we’d need to keep updating the link if there are changes to it. It can also result in orphan pages, which is another pain to deal with.

One may suggest adding a fixed slug entry in the front matter as it takes higher priority. However, this is also troublesome if you already have lots of existing pages without a slug entry, like this very website! Just the thought of having to manually add a slug entry for every single page is already daunting to me, so I’m not gonna do that!

Moreover, I have already set the filename of each source Markdown file of the webpages in a URL-slug-like manner, so why don’t we have Hugo extract the filename and generate a slug from there? This allows me to constantly update the title without worrying about the permalink, as long as I don’t touch the filename!


Luckily, there is a simple solution to that! In newer versions of Hugo (specifically, after v0.144.0), there is a token called :slugorcontentbasename, which does exactly what I want, i.e. extracting the filename to generate the URL slug (unless I specifically provide another slug entry, which takes greater precedence).

Thus, I only need to edit the permalinks key in the site configuration file of this website like so:

[permalinks]
  blog = "/:slugorcontentbasename/"

Hugo will then generate the webpage link based on the filename of the source Markdown file, instead of the title! Mission accomplished!


Further reading:

<< Previous Post

|

Next Post >>