Configuration
This is the single home of site parameters. Every key the theme reads has a row in one of the tables below, giving its type, default and a one-line description, and linking to the guide that covers it. The guides give pasteable snippets and never repeat the definitions. Page-level parameters (front matter) are in Page parameters.
The tables are grouped by function, one ## each, and the anchors are
referenceable — for example /docs/customize/config/#sidebar. An empty
default column means the theme has no default: leave the key out and the
feature is off.
The layers of hugo.yml
An OINK site’s configuration has four kinds of key, and which layer you change depends on what you are changing:
| Layer | Examples | Who defines it |
|---|---|---|
| Hugo’s own top-level keys | baseURL title languages markup outputs taxonomies module |
Hugo itself; the behaviour is on gohugo.io |
Top-level params |
logo offline_search github_repo version page_width comments |
Site-level options the theme reads |
params.ui.* |
navbar_enabled sidebar_width_min typography pager_types |
The shell, navigation and reading interface |
params.<runtime> |
mermaid plantuml drawio markmap |
Each content runtime’s own switch and endpoint |
A minimal working configuration needs only the first two layers:
Configuration principles
- The theme’s defaults are conservative; write only the keys you change. Interactive features (local search, image zoom, comments, feedback, the light/dark menu) are off by default, because the theme does not make policy for a site. Trimming a “complete configuration” leaves behind keys you never needed more readily than adding them as you go.
- There is no theme master switch. There is no
oink.enabled, noparams.oink.*namespace, and no option that swaps between a “Docsy shell” and an “OINK shell”. A switch you cannot find on this page does not exist. - An invalid value warns and falls back to the documented default.
params.ui.typography: solarizedreportsinvalid params.ui.typography "solarized" (allowed: technical | system) -- using "technical"and the site still builds;footer_style: thin,page_width: hugeandsection_index: gridbehave the same way. One typo therefore degrades one setting instead of serving HTTP 500 on every URL underhugo server. It cannot ship silently either: every publishing gate builds with--panicOnWarning, which turns the warning back into a hard failure. - A few things still stop the build, and they are the ones where carrying on would publish something wrong rather than merely plain. A feature needing an external endpoint — PlantUML, Draw.io, Algolia — errors when the endpoint is missing, because the theme never connects to a public service on your behalf. An incomplete upstream attribution errors, because a partial notice reads exactly like a complete one.
params.offline_search_index, thereleasefacts and unresolvable content references do the same.
Page-level override precedence
Hugo’s .Param lookup lets most parameters be overridden per page, highest
precedence first:
- The page’s own front matter;
cascadein an ancestor section’s_index.md(nearer wins);- Site
params.
Drop the ui. prefix when writing it in front matter. The site’s
params.ui.scroll_spy is simply scroll_spy on a page. A ui: block in front
matter is read by nobody and reported by nobody, so a setting that seems to have
no effect is worth checking against
Page parameters first.
A cascade sets a whole subtree at once:
Overrides are for real differences in content. Rebuilding a visual system page by page tends to fall out of step at the next theme upgrade.
The three Goldmark prerequisites
Hugo does not merge a theme module’s markup configuration into the site,
so these three must be in the site’s own hugo.yml, or attribute lines,
component HTML and mathematics all stop working:
Without attribute.block, {.fields}, {.steps} and {caption=…} render as
literal text; without passthrough, \(x\) never becomes a formula; without
unsafe, the structure of steps and cards is escaped away.
renderer.unsafe: true also lets raw HTML in Markdown through. It is meant for
trusted authors, not as a submission filter. Where content comes from untrusted
sources, the review belongs in the contribution process.
Site identity and brand
Hugo’s own top-level keys:
Theme parameters:
params.logo, ,- Brand mark; may point at an
assets/resource or astatic/path — see Brand and appearance
There is no favicon parameter: the theme scans static/ for conventional names
(favicon.ico, favicon.svg, favicon-NxN.png, apple-touch-icon.png,
apple-touch-icon-NxN.png) — see
Brand and appearance.
Shell types and section roots
The shell follows the page type, not the path. Documentation can live in any
directory, with a cascade giving it type: docs.
params.ui.shell_types, ,- Which types use the reading shell with a sidebar — see Layouts and page types
params.ui.docs_section, ,- The documentation section’s root directory name, used for navigation resolution only
params.ui.docs_sidebar_root, ,- With
section, a docs page’s sidebar roots at the documentation section; withhome, at the site home. An invalid value warns and falls back params.ui.quick_links, ,- Top-level menu identifiers listed by the command palette on an empty query — see Command palette
params.ui.sidebar_root_enabled, ,- Allows a subsection to become its own sidebar tree with
sidebar_root_for: self
Blog
Three keys shape a blog section. They apply to the section named by
params.ui.blog_section, and each can be overridden per section through front
matter or a cascade on the blog root.
params.ui.featured_image, ,- How an article renders its own featured image:
nonerenders nothing,bannerframes it above the title in a 16:9 figure,washlays it behind the article header at a tenth of its opacity. The image is whichever one the page already shares in its card andog:image, so the two cannot disagree. An article with no image renders nothing in either mode
Article authorship and series are taxonomies rather than parameters — see Taxonomies and Writing a blog.
Navbar and footer
The fat footer’s column data comes from data/footer/<language>.yaml rather
than from a parameter — see
Navigation and menus.
Sidebar
params.ui.sidebar_cache_limit, ,- Above this page count the site reuses shared navigation markup, and the browser restores the active state
params.ui.sidebar_icon_policy, ,- Icon density:
alleverywhere,groupsonly on the root and nodes with children,nonenowhere. An invalid value warns and falls back toall params.ui.sidebar_headings, ,type: bookonly: expands a heading branch under the current sidebar row; an integer from 2 to 4, andtruemeans 2
How to use the sidebar is in
Layouts and page types; the tree itself comes
from the shape of content/ — see
Organizing content.
Table of contents
The outline’s levels come from Hugo’s own configuration; the theme controls only the tracking behaviour:
Hide the outline on one page with the front matter notoc: true — see
Page parameters.
Pager and page end
The page-end components are in a fixed order — share → feedback → page information → pager → comments — and each has its own switch.
params.ui.pager_types, ,- Which types show previous / next; a page opts out with the front matter
pager: false. An unknown type warns and is dropped params.ui.annotation, ,- The “last modified” and provenance block at the end of the body; the upstream attribution line is driven by the page’s
upstream_linkfamily — see Page parameters
Search and command palette
Local search is off by default, and the command palette appears only once it is
on (the navbar magnifier, Cmd/Ctrl with K, /, \).
params.offline_search, ,- Generates one local index per language and enables the command palette — see Search
params.offline_search_on_serve, ,- Builds the index under
hugo servertoo, so the preview behaves like production; setfalseon a very large site to speed up local rebuilds params.offline_search_index, ,- Index scope, cumulative:
title,heading,summary,content. An invalid value fails the build params.ui.command_palette.commands, ,- Custom commands, each with either
urlor a built-inaction— see Command palette
A custom command record accepts seven keys only — id, title, description,
icon, keywords, url, action — and id must match ^[a-z][a-z0-9_-]*$
and must not collide with a built-in action ID. Per-language titles go under
languages.<lang>.params.ui.command_palette.commands.
Keyboard
Image zoom
Which images become zoom candidates is in Images.
Typography
Custom fonts and colours go through the SCSS entry points rather than YAML — see Brand and appearance.
Comments and feedback
params.comments.enable, ,- The site-level comment switch; a page overrides it with the front matter
comments— see Comments params.comments.giscus.term,- The discussion title or number when
mappingisspecificornumber; the attribute is omitted when unset params.comments.giscus.lang, ,- The giscus interface language. Unset, a Chinese site resolves
zh-CN/zh-TW/zh-HK, other languages take the base language code, and anything giscus does not support falls back toen params.comments.giscus.ariaLabel, ,- The
aria-labelon the comment container; the default is English, so a multilingual site writes one per language params.comments.giscus.errorMessage, ,- Text shown when loading fails; the default is English, so a multilingual site writes one per language
Missing any one of the four required giscus values leaves the comment section unrendered: no error, and nothing appears.
Repository links and page information
params.github_repo,- The content repository URL, resolving “edit this page”, “view history”, “create child page” and “open a documentation issue” — see Repository links and page info
params.github_project_repo, ,- The product repository URL, for “open a project issue” and the navbar GitHub entry
params.github_url, ,- Removed; write
params.github_repo. The migration registry that used to name the replacement is gone, so an old key is now simply an unread key params.ui.lastmod_commit, ,- What follows “last modified”:
subjectthe commit subject,hashthe short hash,nonenothing. An invalid value warns and falls back
Content runtimes
Mermaid, KaTeX, ECharts, Infographic, Asciinema, Swagger UI and Redoc are detected from the content and load only where a page uses them; they have no site switch. Only these need a switch or an external endpoint:
params.markmap, ,- Enables the mind map fence site-wide — see Markmap
params.mermaid,- Configuration passed to
mermaid.initialize(); keys are lowercase, and dark mode overridesthemeautomatically params.plantuml.enable, ,- Enables the PlantUML fence — see PlantUML
params.plantuml.svg_image_url,- The PlantUML service’s SVG endpoint; required when enabled, and its absence fails the build
params.drawio.enable, ,- Enables the edit button on
.drawio.svgimages — see Draw.io params.drawio.drawio_server,- The Draw.io editor address; required when enabled, and its absence fails the build
Mathematics needs no parameter, only the
passthrough prerequisite.
Output formats
The theme declares two custom output formats and does not enable them for a
site: request what you want under outputs.
| Format | Output | Description |
|---|---|---|
HTML |
index.html |
The interactive form; required |
markdown |
index.md |
Each page’s plain Markdown twin, which “copy Markdown” and “view source” depend on — see AI-agent support |
LLMS |
llms.txt |
A plain-text format the theme declares, usually attached to home only |
print |
_print/index.html |
The whole-section print page the theme declares — see Print |
RSS |
index.xml |
Hugo’s own; attach it to section so every section has a feed |
Two parameters for print output:
Languages and versions
Languages are defined with Hugo’s own languages block, and the theme only
reads the translation relationships it establishes:
Paired files, anchor alignment and fallback for untranslated pages are in Languages.
Version parameters:
params.version,- The identifier of this site variant, which need not be a Git ref — see Versions
Miscellaneous
taxonomies,- Hugo’s own: enables
tag: tags/category: categories— see Taxonomies services.googleAnalytics.id,- Hugo’s own: the analytics script is injected in production builds only — see Analytics and SEO
Verifying a configuration change
Run a strict build after changing configuration:
It passes only when the output reads Total in … with no ERROR and no WARN.
Common errors and what they mean:
| Error fragment | Cause |
|---|---|
invalid params.ui.typography |
The presets are technical and system |
invalid footer_style … (allowed: fat | slim | none) |
A bad footer style; the error names the page |
invalid page_width … (allowed: normal | wide | full) |
A bad page width |
invalid params.ui.section_index … (allowed: list | cards) |
A bad section index style |
invalid params.offline_search_index |
The scopes are title, heading, summary, content |
params.plantuml.enable requires an explicit params.plantuml.svg_image_url |
PlantUML enabled with no endpoint |
params.drawio.enable requires an explicit params.drawio.drawio_server |
Draw.io enabled with no server address |
params.search.algolia requires explicit appId, apiKey, and indexName |
All three Algolia values are required |
params.ui.image_zoom must be a boolean |
Written as the string "true" |
command … must define exactly one of url or action |
A custom command gave both url and action, or neither |
invalid params.ui.sidebar_icon_policy …; using all |
Only a warning, but the value is misspelled |
A configuration change also needs at least three checks: one page in each
language, a page with no translation to see the fallback, and the links under
the production baseURL (easy to miss on a subpath deployment).
The theme’s declared Hugo floor is 0.160.1, and the currently verified version
is 0.164.0. Building against both after a configuration change catches
anything that only works on the newer one:
The floor is declared in the theme’s hugo.yaml and theme.toml, and a site’s
own module.hugoVersion.min should agree with it.
Related
- Brand and appearance — site name, logo, colours, fonts
- Navigation and menus — navbar menu, page actions, footer
- Layouts and page types — shell, sidebar, table of contents
- Page parameters — the full front matter table
- Troubleshooting — locating a build failure