v0.4.0 is out — data-driven components and integrated graphics. Read the notes
projectious·theme
On this page

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?#

FilePurposeMaintained by
hugo.tomlSite URL, module, languages, menus, outputs, Markdown and theme parametersSite owner
go.modHugo Module dependency and selected theme versionSite owner
package.json / lockfileTailwind CLI and browser-test toolsSite owner
data/cdn.yamlExact KaTeX, Mermaid and asciinema runtime versionsTheme maintainer
i18n/*.tomlTranslated interface labelsTheme maintainer or translator
Page front matterTitle, order, description and per-page capabilitiesContent 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#

hugo.toml
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 = true

baseURL 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.

hugo.toml
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.

FormatWhat the theme producesWhy enable it
SearchIndex/index.json with pages and H2/H3 headingsHeader search and command palette
Printprint.html for an entire sectionPrintable handbook/PDF workflow
Markdownindex.md beside each pageCopy/View Markdown actions and agent consumption
LLMS/llms.txt with language-aware page linksA compact discovery file for LLM tools
RSSXML feeds styled by feed.xslRelease-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.

ParameterType and defaultConfigure whenDetails
descriptionstring, emptySetting site metadataHeader and navigation
githubURL, unsetShowing a repository header actionHeader and navigation
brandtable, projectious.work defaultsReplacing wordmark, marks and favicons without template overridesHeader and navigation
editURLURL or language map, unsetShowing Edit-this-page linksEditing and feedback
versionstring, unsetLabelling the current documentationVersioning
versionMenuLabelstring, current versionGiving the version menu an independent labelVersioning
versionsarray, emptyLinking published documentation treesVersioning
versionProbeboolean, trueDisabling same-page version probing globallyVersioning
sidebarSectionsstring array, ["docs"]Putting the sidebar on other sectionsHeader and navigation
sidebarOpenDepthinteger, 0Changing initially expanded levelsHeader and navigation
codeThemeadaptive or dark, adaptiveForcing code and terminal panels darkTailwind and design tokens
darkSurfacenavy, unsetMaking navy the initial dark surfaceAccessibility
announcementtable, unsetShowing a dismissible noticeHeader and navigation
feedbackEndpointURL, unsetSending page votes to a serviceEditing and feedback
selfHostAssetsboolean, falseReplacing public CDN URLsDependencies
mathboolean, falseLoading KaTeX on every pageMathematics
searchboolean, trueDisabling search and its indexSearch
feedbackboolean, trueHiding the page-vote controlEditing and feedback
accessibilityMenuboolean, trueHiding reader preference controlsAccessibility
sidebarFilterboolean, trueHiding the sidebar filterSearch
commandPaletteboolean, trueDisabling the keyboard paletteHeader and navigation
build.tailwindboolean, trueBuilding without Node/TailwindTailwind and design tokens

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:

sh
python3 -m venv .venv
. .venv/bin/activate
pip install -r scripts/requirements.txt
./scripts/notebooks.sh

It 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:

text
User-agent: *
Disallow: /search/
Disallow: /*/print.html
Sitemap: https://docs.example.com/sitemap.xml

llms.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:

text
# 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.

Edit this page Updated Aug 26, 2026 Reference