iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article

Mastering Hugo: A Comprehensive Guide to PaperMod

に公開

This article is about how to publish project pages using Hugo + GitHub Pages. Please refer to the previous article for the overall flow.

https://zenn.dev/akitek/articles/4cf2fb5b4a9e0e

In reality, since the method of updating/publishing and global page settings vary depending on the selected Hugo theme, a more detailed explanation is required for proper management.

Here, I will explain PaperMod, which is my favorite and is actually used for my public pages. The following page includes a demo, making it easy to reference even if you just want to try out the design.
https://themes.gohugo.io/themes/hugo-papermod/

(2026/02/03: Addition)
I have shared an article on creating custom site icons for use with PaperMod.

Hugo: What is PaperMod?

https://adityatelange.github.io/hugo-PaperMod/

It features a simple page design with article lists, archives, and search functionality.

Additionally, three designs are available for the home screen.

Homeinfo Mode

A brief introductory comment and links to various SNS accounts are displayed at the top, followed by the latest articles below.

Profile Mode

A home screen with only an icon. The information is minimal and easy to read 🤩

Configuration Items

The configuration for the entire website is described in hugo.yaml. While it includes various settings, I will limit the explanation here to the essential ones you should know.

https://github.com/adityatelange/hugo-PaperMod/wiki/Variables

Global Page Information

baseURL: "https://***.github.io/" # Set the base URL within the page. Important!!
languageCode: "ja-JP"
title: "Page Title"
theme: ["PaperMod"] # Hugo theme setting

First are the global configuration items. Make sure to include at least the ones listed above.
Regarding baseURL, since it serves as the base for URL information described throughout the website, be sure to write the URL of your published GitHub Pages.

menu:
  main: # Header tab information
    - identifier: about # Adding About page (md filename to reference)
      name: about # Page name displayed on the web
      url: about/ # Corresponding URL
      weight: 10 # Display order priority in the menu bar
    - identifier: member # Adding member page
      name: member
      url: member/
      weight: 11
    - identifier: search # Adding search page
      name: search
      url: search/
      weight: 12
    - identifier: tags
      name: tags
      url: tags/
      weight: 13
    - identifier: archives
      name: archives
      url: archives/
      weight: 14

Under menu, you can manage the navigation links to each page located in the menu bar at the top of the site. In this configuration, the about, member, search, tags, and archives pages have been added. The about and member pages were added to the original design.

If you want to add a new page, you will add it to this menu section.
By the way, pages you wish to add should be created as /test-site/content/***.md.
Note that weight affects the order of the page names in the menu bar.
For example, the order about, member, search, tags, archives is determined by:
about(weight = 10) > member (weight = 11) > search (weight = 12) > tags (weight = 13) > archives (weight = 14).

Detailed Settings

You can configure the page settings in more depth.

General Settings
  env: production # to enable google analytics, opengraph, twitter-cards and schema.
  title: "Title"
  description: "ExampleSite description"
  keywords: [Blog, Portfolio, PaperMod]
  author: Me
  # author: ["Me", "You"] # multiple authors
  images: ["<link or path of image for opengraph, twitter-cards>"]
  DateFormat: "January 2, 2006" # Article creation date
  defaultTheme: auto # Page theme setting. "dark" or "light" can also be set
  disableThemeToggle: false # Whether to show the dark/light toggle button

  ShowReadingTime: true      # Whether to show the estimated reading time for each article
  ShowShareButtons: false    # Whether to show share buttons at the bottom of each article
  ShowPostNavLinks: true     # Whether to show navigation links to the previous and next posts
  ShowBreadCrumbs: true      # Whether to show breadcrumbs for each article's hierarchy
  ShowCodeCopyButtons: false # Whether to show buttons to copy code blocks within articles
  ShowWordCount: true        # Whether to show the word count for each article
  ShowRssButtonInSectionTermList: true # Whether to show the RSS button
  UseHugoToc: true # 
  disableSpecial1stPost: false # Whether to show the special 1st post
  disableScrollToTop: false # Whether to show the scroll-to-top button
  comments: true # Whether to show comments on articles
  hidemeta: false # Whether to hide meta information from search results
  hideSummary: false # Whether to hide the summary from search results (can be set individually for each article)
  showtoc: true  # Whether to show the TOC (Table of Contents)
  tocopen: false # Whether the TOC should be expanded by default

This section contains many settings related to the display of individual articles. For example, showtoc determines whether to display a ToC (Table of Contents) at the beginning of each Markdown article. Also, ShowBreadCrumbs can display a breadcrumb trail showing the page hierarchy of each article.

Basically, I think it's good to reuse these settings...

Home Settings
  label: # Title information at the top of the header
    text: "Home"
    icon: /apple-touch-icon.png
    iconHeight: 35

  # profile-mode
  profileMode:
    enabled: false # needs to be explicitly set
    title: ExampleSite
    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: "Welcome!! \U0001F44B"
    Content: >
      👋 Welcome to the study sharing session!!

      - The site is currently under construction 😇

      - In the meantime, please refer to the past minutes!!

  socialIcons: # Various service icons to be displayed on the home screen
    - name: x
      url: "https://x.com/"
    - name: stackoverflow
      url: "https://stackoverflow.com"
    - name: github
      url: "https://github.com/"
    - name: discord
      url: "https://discord.gg/"

These settings determine whether the home screen display should be in ProfileMode or HomeinfoMode, as mentioned earlier, along with their respective configuration items. The default is HomeinfoMode, so if you prefer ProfileMode, set it as follows:

profileMode:
    enabled: true # needs to be explicitly set

socialIcons refers to the accounts and icons for the services you use. If you change the name field, the icon will be updated automatically. Please refer to the page below and set up the accounts you need.

https://github.com/adityatelange/hugo-PaperMod/wiki/Icons

Cover Images & Edit Instructions
  cover:
    hidden: true            # Whether to display cover images at all
    hiddenInList: true      # Whether to show cover images on the Home and List pages
    hiddenInSingle: false   # Whether to show cover images on individual article pages
    responsiveImages: false # Whether to reduce image size
    linkFullImages: false   # Whether to add hyperlinks to images

  editPost: # Button to request edits for an article
    URL: "https://github.com/<path_to_repo>/content" # Jumps to the GitHub page of the article
    Text: "Suggest Changes" # edit text
    appendFilePath: true # to append file path to Edit link

cover is a configuration item regarding whether to display cover images for each article. This section manages information for the entire site.
Then, the specific image URL to be displayed as a cover is written in the Markdown file of each individual article.

For example, you can include the following settings in /content/member.md when creating a member page.

member.md
---
title: "Member"
layout: "member"
url: "/member/"
summary: member
date: 2025-07-09
author: ["Akitek"]
cover:
  image: "images/tn.png" # If you want to add a cover image [place it in assets/images]
  hiddenInList: true
---

editpost is a setting to include a process in each article that navigates to the corresponding GitHub page to request edits. (It is unclear in what specific situations this would be used.)

Article Search Functionality

In my opinion, one of the appeals of PaperMod is the search functionality for past articles.
There are configuration items (fuseOpts) related to this search function (search).
You can configure various aspects such as the search method, documents to be targeted, and display content.

  # for search
  # https://fusejs.io/api/options.html
  fuseOpts: # Settings for the search function
    isCaseSensitive: false # Whether to distinguish between uppercase and lowercase
    shouldSort: true # Whether to sort articles by score
    location: 0 # 
    distance: 1000
    threshold: 0.4
    minMatchCharLength: 0
    limit: 10 # Maximum number of search results displayed refer: https://www.fusejs.io/api/methods.html#search
    keys: ["title", "permalink", "summary", "content"] # Elements to be searched in each article (searches for text within the elements included here)

Specific Examples of Adding Pages & Articles

Now that we've looked at the general page settings in hugo.yaml, let's look at specific examples in terms of operation.
Suppose the folder hierarchy is as follows:

.
├── archetypes
│   └── default.md
├── assets # Place various cover images and images here
│   └── images
│       └── tn.png
├── content # Place pages and articles here
│   ├── about.md
│   ├── archives.md
│   ├── member.md
│   ├── posts
│   │   └── testpost.md
│   └── search.md
├── data
├── hugo.yaml # Management information for the entire page
├── i18n
├── layouts
├── public # Things to push to GitHub Pages
├── static
└── themes
    └── PaperMod

Adding New Pages or Articles

First, if you want to add a page, create a file like test.md under /content/. This test will become the page name.
To display this page in the menu bar, edit hugo.yaml.

hugo.yaml
menu:
  main: # Header tab information
    - identifier: about # Adding About page (reference md name)
      name: about # Page name displayed on the web
      url: about/ # Corresponding URL
      weight: 10 # Priority of display order in the tab
    - identifier: member # Adding member page
      name: member
      url: member/
      weight: 11
    - identifier: search # Adding search page
      name: search
      url: search/
      weight: 12
    - identifier: tags
      name: tags
      url: tags/
      weight: 13
    - identifier: archives
      name: archives
      url: archives/
      weight: 14
    - identiifier: test
      name: test
      url: test/
      weight: 15

In this state, try running hugo server, and if it's reflected at http://localhost:1313/, it's a success.

Next, regarding adding articles. In a dedicated page, when posting an article, create ***.md under /content/posts/. In the example above, an article called /content/posts/testpost.md has been created. By adding it here, it will also be reflected on the Home screen, archives, and search.
Unlike dedicated pages, no action is required in hugo.yaml.

Reflecting to GitHub Pages

Now, as previously explained, to publish the pages and articles created locally, you should copy the folders under /public/ to your local repository (cloned from the GitHub repository) and then push to the remote.

However, I personally got stuck on the reflection of the link information associated with each page.
In fact, I would like you to check: is the link information in /public/index.xml correct?

In some cases, links like localhost:1313/ are scattered everywhere. If you push this to GitHub Pages as is, page transitions on the public site will fail (for example, if the link is localhost:1313/about, the transition won't work because that page isn't published on the internet).

Therefore, to ensure the link information of your created web pages is correct, you must perform the following two steps.

Configuring baseURL

Replace the baseURL in hugo.yaml with your public URL https://***.github.io/.

hugo.yaml
baseURL: "https://[username].github.io/"
languageCode: "ja-JP"
title: "Title"
theme: ["PaperMod"]

Building the created web page

Basically, you do not edit the content under /public/ directly. Elements added or updated in /content/ will be automatically reflected in /public/ by building with the hugo command.[1]

You can easily build by running the $ hugo command in the root directory of your local web page (/test-site).

Push the folders under /public/ after this build to GitHub Pages.

Additionally, you can check if the link information is correct by inspecting /public/index.xml.

Summary

In this article, I explained how to add pages/articles and publish them using the Hugo theme PaperMod.
Hugo offers a variety of themes, but the methods for adding and publishing content differ for each one.
Therefore, if you want to try other themes, please make sure to read the project documentation for each specific theme carefully.

Reference Sites

https://themes.gohugo.io

Various themes are available for Hugo. Feel free to publish your project page using a theme you like!

https://qiita.com/2Gken1029/items/c7eadefc45590cc55a5e

This article helped me solve the issue where link information wasn't being reflected correctly. Be sure to follow the advice in this article (speaking from experience).

Postscript:

In Hugo, icons for famous websites and social media can be freely configured and used within the .yaml file.
Conversely, service icons for platforms like Qiita or Zenn are not provided by default.
However, according to the following article, it is possible to create and use your own custom service icons.

https://qiita.com/amuyikam/items/1944f821e7a099da49bf

脚注
  1. Conversely, please note that if you do not build, the content in /public/ will remain outdated even if you push it to GitHub Pages. ↩︎

Discussion