Site-wide configuration
Configure Hugo, outputs, Markdown, menus, languages and theme parameters.
Configure the theme in layers. Start with Hugo’s site configuration, add theme parameters for presentation and integrations, then use front matter for page-level choices. Do not edit theme templates for settings that already have a parameter.
Which configuration files exist?#
| File | Purpose | Maintained by |
|---|---|---|
hugo.toml | Site URL, module, languages, menus, outputs, Markdown and theme parameters | Site owner |
go.mod | Hugo Module dependency and selected theme version | Site owner |
package.json / lockfile | Tailwind CLI and browser-test tools | Site owner |
data/cdn.yaml | Exact KaTeX, Mermaid and asciinema runtime versions | Theme maintainer |
i18n/*.toml | Translated interface labels | Theme maintainer or translator |
| Page front matter | Title, order, description and per-page capabilities | Content author |
The example at src/content/hugo.toml is executable test material. The copyable
equivalent is included below so a site creator does not need to browse the theme
repository.
Minimum site configuration#
baseURL = "https://docs.example.com/"
title = "Example documentation"
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = false
enableRobotsTXT = true
[module]
[[module.imports]]
path = "github.com/projectious-work/brand-theme-hugo-vanilla"
[build.buildStats]
enable = truebaseURL must include any deployment prefix. The theme resolves internal links
through Hugo so /project-name/ deployments work correctly.
Complete copyable configuration#
Paste this into the site-root hugo.toml created by hugo new site, then replace
the example identity and repository values. Comments mark optional settings.
baseURL = "https://docs.example.com/" # Canonical URL, including any path prefix.
title = "Example documentation" # Site name used in metadata and the header.
defaultContentLanguage = "en" # English is served when no language is specified.
defaultContentLanguageInSubdir = false # Keep the default language at the site root.
enableRobotsTXT = true # Ask Hugo to generate the theme's robots.txt.
[module] # Install the theme as a versioned Hugo Module.
[[module.imports]]
path = "github.com/projectious-work/brand-theme-hugo-vanilla" # Theme module.
[build.buildStats] # Let Tailwind discover classes emitted by Hugo templates.
enable = true
[security.exec] # Permit only the build tools the site intentionally invokes.
allow = ["^(dart-)?sass$", "^go$", "^git$", "^node$", "^postcss$", "^tailwindcss$"]
[outputFormats.SearchIndex] # Local full-text search data at /index.json.
mediaType = "application/json" # JSON response type.
baseName = "index" # Output filename without extension.
isPlainText = true # Do not wrap the generated JSON in HTML.
notAlternative = true # Keep this out of alternate-format metadata.
[outputFormats.Print] # Printable aggregate for each section.
mediaType = "text/html" # Browser-renderable output.
baseName = "print" # Produces print.html.
isHTML = true # Enable Hugo's HTML processing.
notAlternative = true # Do not advertise it as an alternate page.
permalinkable = true # Give the output a stable URL.
[outputFormats.LLMS] # Machine-readable discovery document at /llms.txt.
mediaType = "text/plain" # Plain UTF-8 text.
baseName = "llms" # Output filename without extension.
isPlainText = true # Do not apply an HTML wrapper.
notAlternative = true # Keep it out of alternate-format metadata.
[outputFormats.Markdown] # Clean Markdown representation of pages and sections.
mediaType = "text/markdown" # Standard Markdown response type.
isPlainText = true # Do not apply an HTML wrapper.
permalinkable = true # Give every representation a stable URL.
[outputs] # Select the formats generated for each Hugo page kind.
home = ["HTML", "RSS", "SearchIndex", "LLMS"] # Site-level discovery outputs.
section = ["HTML", "RSS", "Print", "Markdown"] # Section aggregates and copies.
page = ["HTML", "Markdown"] # Reader page plus clean Markdown.
[markup.goldmark.renderer] # Markdown-to-HTML safety policy.
unsafe = false # Reject raw HTML from content files.
[markup.goldmark.extensions.passthrough] # Preserve formulas for KaTeX.
enable = true
[markup.goldmark.extensions.passthrough.delimiters] # Accepted LaTeX delimiters.
block = [["\\[", "\\]"], ["$$", "$$"]] # Display formulas.
inline = [["\\(", "\\)"]] # Formulas inside prose.
[markup.highlight] # Hugo Chroma syntax highlighting.
noClasses = false # Emit semantic classes so the theme controls colours.
guessSyntax = true # Highlight an unlabelled fence when detection succeeds.
[markup.tableOfContents] # Headings used by the right-hand navigation.
startLevel = 2 # Begin with H2.
endLevel = 3 # Include H3, but not deeper headings.
[[menus.main]] # Add a link to the primary header navigation.
name = "Documentation" # Reader-facing label.
pageRef = "/docs" # Hugo page reference; checked during the build.
weight = 10 # Lower weights appear first.
[params] # Public theme settings; defaults are documented below.
description = "Documentation for the example product." # Site metadata summary.
github = "https://github.com/example/example-docs" # Repository header link.
editURL = "https://github.com/example/example-docs/edit/main/content/" # Edit base URL.
version = "v1.0" # Current label in the version menu.
codeTheme = "adaptive" # Adapt code panels to light and dark modes.
sidebarSections = ["docs"] # Top-level sections that receive the docs rail.
sidebarOpenDepth = 0 # Initially expanded sidebar levels.
[params.brand] # Optional product identity; every key has this default.
home = "/"
wordmark = "projectious.work"
markLight = "logo/icon-light.svg"
markDark = "logo/icon-dark.svg"
favicon32 = "logo/icon-light.svg" # high-contrast mark for light browser chrome
appleTouchIcon = "logo/apple-touch-icon-180.png"
[[params.versions]] # One published documentation version.
label = "v1.0" # Menu label.
url = "/" # Deployment-relative root for this version.
note = "latest" # Optional status annotation.The packaged defaults use the latest mark-5a logo. Every supplied colour and
monochrome variant is also shipped under logo/theme/, so a site can select a
different approved mark without copying or modifying the theme.
Required output formats#
HTML works without custom outputs. The integrated search, printing, Markdown copy
and llms.txt features require the [outputFormats] and [outputs] blocks from
the example configuration.
| Format | What the theme produces | Why enable it |
|---|---|---|
SearchIndex | /index.json with pages and H2/H3 headings | Header search and command palette |
Print | print.html for an entire section | Printable handbook/PDF workflow |
Markdown | index.md beside each page | Copy/View Markdown actions and agent consumption |
LLMS | /llms.txt with language-aware page links | A compact discovery file for LLM tools |
RSS | XML feeds styled by feed.xsl | Release-note subscriptions |
Add SearchIndex and LLMS to outputs.home; add Print and Markdown to
sections; add Markdown to pages. The example configuration shows the exact media
types and filenames.
Markdown configuration#
Copy the example [markup] block to enable:
- Goldmark passthrough delimiters for KaTeX;
- class-based Chroma syntax highlighting;
- H2/H3 tables of contents; and
- safe Markdown rendering with raw HTML disabled.
Turn markup.goldmark.renderer.unsafe on only when your own trusted content needs
raw HTML. The theme itself does not require it.
Theme parameters#
Place these below [params] in hugo.toml:
The table is the complete public parameter set. Scalar parameters are assigned
below [params]; tables and arrays use the TOML shapes shown in their detailed
pages.
| Parameter | Type and default | Configure when | Details |
|---|---|---|---|
description | string, empty | Setting site metadata | Header and navigation |
github | URL, unset | Showing a repository header action | Header and navigation |
brand | table, projectious.work defaults | Replacing wordmark, marks and favicons without template overrides | Header and navigation |
editURL | URL or language map, unset | Showing Edit-this-page links | Editing and feedback |
version | string, unset | Labelling the current documentation | Versioning |
versionMenuLabel | string, current version | Giving the version menu an independent label | Versioning |
versions | array, empty | Linking published documentation trees | Versioning |
versionProbe | boolean, true | Disabling same-page version probing globally | Versioning |
sidebarSections | string array, ["docs"] | Putting the sidebar on other sections | Header and navigation |
sidebarOpenDepth | integer, 0 | Changing initially expanded levels | Header and navigation |
codeTheme | adaptive or dark, adaptive | Forcing code and terminal panels dark | Tailwind and design tokens |
darkSurface | navy, unset | Making navy the initial dark surface | Accessibility |
announcement | table, unset | Showing a dismissible notice | Header and navigation |
feedbackEndpoint | URL, unset | Sending page votes to a service | Editing and feedback |
selfHostAssets | boolean, false | Replacing public CDN URLs | Dependencies |
math | boolean, false | Loading KaTeX on every page | Mathematics |
search | boolean, true | Disabling search and its index | Search |
feedback | boolean, true | Hiding the page-vote control | Editing and feedback |
accessibilityMenu | boolean, true | Hiding reader preference controls | Accessibility |
sidebarFilter | boolean, true | Hiding the sidebar filter | Search |
commandPalette | boolean, true | Disabling the keyboard palette | Header and navigation |
build.tailwind | boolean, true | Building without Node/Tailwind | Tailwind and design tokens |
Menus and languages#
Define primary links under menus.main; use pageRef for local pages. Define each
language under [languages.<code>] with label and weight. See
Header and navigation and
Internationalization for complete examples.
Edit and feedback integrations#
See Editing and feedback for repository URL mapping, the request payload, the browser’s one-vote-per-page behavior and the security requirements for an optional receiving service.
Notebook conversion#
Notebook conversion is an optional pre-build operation:
python3 -m venv .venv
. .venv/bin/activate
pip install -r scripts/requirements.txt
./scripts/notebooks.shIt writes shared Markdown below content/_notebooks/ and images below
static/notebooks/. The shortcode checks a page resource first, then the shared
path. Notebook basenames must be unique.
Search engines and llms.txt#
robots.txt gives compliant web crawlers crawl instructions. Set
enableRobotsTXT = true; Hugo then asks the theme to publish /robots.txt. The
theme allows canonical content while excluding generated search indexes and print
variants that duplicate it. For example:
User-agent: *
Disallow: /search/
Disallow: /*/print.html
Sitemap: https://docs.example.com/sitemap.xmlllms.txt is a discovery document, not a crawler rule. Enable it by defining the
LLMS output format and adding "LLMS" to outputs.home, as in the copyable
configuration. It contains page titles, descriptions and links to clean Markdown
representations, without repeated header, sidebar and footer controls:
# Example documentation
## Documentation
- [Getting started](https://docs.example.com/docs/getting-started/index.md): Create a site.Neither file is access control. Private information must not be published; use authentication at the hosting layer when content requires access restrictions.
Validate configuration changes#
Run ./scripts/verify.sh. It builds twice, compares artifacts, rejects project-base
URL escapes and runs desktop/mobile browser tests. A configuration change is not
complete until that command passes without warnings.