916 Words
4 min Reading time
Published 2026-11-07

Configuration guide#

This page explains how to configure the theme: what ships with the theme, what must live in your own site, what each parameter does, and the mistakes that are easy to make. Work through it in order and you have a running blog.

Three layers of configuration#

FilePurposeDo you edit it?
Theme hugo.tomlBuilt-in defaults, merged into your site by HugoNo, override only what you need
Your site hugo.tomlYour site configurationYes, required
exampleSite/hugo.tomlDemo site config, including self-test mountsReference only
Warning

Do not copy exampleSite/hugo.toml wholesale. Its [module] section mounts ../layouts and ../assets from the parent directory, which only works when the repository root is the theme itself. Once installed under themes/helloblog those paths do not exist and the build fails.

Minimum working configuration#

This is all a new site needs:

baseURL = 'https://your-domain.com/'
title = 'My Blog'
timeZone = 'Asia/Shanghai'
theme = 'helloblog'

# Generate robots.txt pointing at the sitemap
enableRobotsTXT = true

# Filter tags in place on /tags/ instead of generating /tags/<term>/ pages
disableKinds = ['term']

# Extra JSON output for the home page, required by search
[outputs]
  home = ['html', 'rss', 'json']

# Items per list page
[pagination]
  pagerSize = 6

# Keep only the tag taxonomy
[taxonomies]
  tag = 'tags'
Warning

outputs.home must include json. Without it search silently returns nothing, and no error is shown.

Settings that only work at site level#

Hugo merges only tables such as params, taxonomies and markup from a theme. The following are site-level and have no effect in the theme’s hugo.toml:

SettingPurpose
outputsHome page JSON index for search
paginationList page size
services.rssRSS item limit
imagingImage quality and resampling
sitemapCrawl hints
moduleHow the theme is installed

Theme parameters#

[params] already has sensible defaults; only write what you want to change.

ParameterDefaultDescription
descriptionemptySEO fallback description, page front matter wins
keywordsemptySEO fallback keywords
imagesog-cover.pngDefault social share image, placed in static/
color_themesakurasakura / purple / ink / cyan / blue
glass_opacity0.5Glassmorphism opacity, 0–1
siteageemptySite launch date; leave empty to hide the day counter
avataravator.webpSidebar avatar, relative to static/
sayingemptyOne-line sidebar quote, falls back to the i18n string

Home page#

[params.index]
  logo = ''                     # Big home title, falls back to site.Title
  welcome = ['Hello, world']    # Typewriter lines, loops through the list
  increase_speed = 60           # Typing interval (ms)
  decrease_speed = 40           # Deleting interval (ms)
  loop_speed = 1000             # Pause before switching lines (ms)
  particle_enable = true        # Particle background
  particle_distance = 180       # Distance threshold for particle links

Background#

[params.background]
  enable = true
  image = 'background.webp'     # Relative to static/
  overlay_dark = 0.6            # Dark mode overlay strength
  overlay_light = 0.5           # Light mode overlay strength

Comments#

Comments are off by default. Configure giscus first, otherwise comments are posted to someone else’s repository.

[params.giscus]
  enable = true
  repo = 'owner/repo'
  repo_id = 'R_xxx'
  category = 'General'
  category_id = 'DIC_xxx'
  mapping = 'pathname'
  strict = '0'
  reactions_enabled = '1'
  emit_metadata = '0'
  input_position = 'bottom'

Multilingual#

Translations are matched by filename: content/about/index.md pairs with content/about/index.en.md.

defaultContentLanguage = 'zh'
defaultContentLanguageInSubdir = false   # Default language served at the root

[languages]
  [languages.zh]
    languageName = '中文'
    languageCode = 'zh-cn'
    weight = 1
  [languages.en]
    languageName = 'English'
    languageCode = 'en'
    weight = 2

Data files are language-aware too: the default is data/link.json, and the English site automatically reads data/link-en.json (music works the same way).

Navigation is menu-driven, so adding a link does not require template changes:

[[menus.main]]
  identifier = 'nav.posts'   # Maps to the nav.posts i18n key
  name = 'Posts'             # Fallback label when identifier is missing
  url = 'posts/'             # Relative URL, language prefix added automatically
  weight = 1

When identifier matches a nav.* key in i18n/*.toml, the translated label wins. Keep url relative; the English site turns it into /en/posts/.

Content and fields#

Posts are page bundles at content/posts/<slug>/index.md.

---
title: Post title
date: '2026-10-23'
lastmod: '2026-11-07'
category: Tech
tags: [hugo, markdown]
description: Post summary
keywords: [hugo, markdown]
draft: false
---
FieldPurpose
titleTitle used in the page head and search index
datePublish date, lists and archive sort by it descending
lastmodUpdate date; the update block shows only when it differs from date
categoryGroups posts on the archive page
tagsTag cloud and filtering
descriptionMeta description, falls back to the site description
keywordsMeta keywords, an array is recommended
draftBuilt into Hugo, excluded from builds when true
historyOptional changelog array, also feeds the home page heatmap

Data files#

Friend links and the music player read from your site’s data/ directory, not from the theme:

  • data/link.json: friend links
  • data/music.json: playlist

For a bilingual site, add link-en.json and music-en.json next to the defaults. No configuration change is needed.

FAQ#

QSearch returns nothing
ACheck that outputs.home includes json and that /index.json is reachable
QComments do not show
ACheck that params.giscus.enable is true and repo_id / category_id are filled in
QLanguage switch 404s
AA translation must live next to the original with a language suffix, e.g. index.en.md
QTheme parameters have no effect
ASite-level settings such as outputs, pagination, imaging and sitemap are ignored inside a theme

Pre-launch checklist#

  • Replace baseURL with your real domain
  • Replace params.description and params.images
  • Set siteage to your launch date
  • Confirm hugo --minify builds with zero errors
  • If comments are enabled, verify giscus loads correctly
Contents
Configuration guide Three layers of configuration Minimum working configuration Settings that only work at site level Theme parameters Home page Background Comments Multilingual Navigation menu Content and fields Data files FAQ Pre-launch checklist

No song selected

Unknown artist

0:00 0:00