Configuration

Configure Oink with Hugo settings and focused theme parameters.

OINK follows a “native first” configuration model. Site identity, languages, menus, outputs, taxonomies, markup, and modules stay in their Hugo-defined locations. Existing Docsy parameters remain where their semantics are useful. OINK adds only focused choices for behavior that cannot be inferred.

Configuration rules

  1. Prefer Hugo configuration over a theme-specific duplicate.
  2. Prefer an established Docsy parameter over an OINK synonym.
  3. Put brand, content, repository, and UI choices in their semantic locations.
  4. Keep internal vendor paths and template composition out of the public API.
  5. Fail early for invalid values or a missing required endpoint.

There is no oink.enabled flag and no params.oink.* tree. Adding either would create a second theme mode and make every fix, test, and document ambiguous.

A complete baseline

This example makes English primary and Simplified Chinese secondary:

YAML
title: Product Documentation
baseURL: https://docs.example.com/
defaultContentLanguage: en
enableRobotsTXT: true

languages:
  en:
    label: English
    locale: en-US
    weight: 1
    title: Product Documentation
    menus:
      main:
        - { name: Docs, pageRef: /docs, weight: 10 }
        - { name: Blog, pageRef: /blog, weight: 20 }
  zh:
    label: 简体中文
    locale: zh-CN
    weight: 2
    title: 产品文档
    menus:
      main:
        - { name: 文档, pageRef: /docs, weight: 10 }
        - { name: 博客, pageRef: /blog, weight: 20 }

outputs:
  home: [HTML]
  section: [HTML, RSS, print]

markup:
  goldmark:
    renderer:
      unsafe: true
    extensions:
      passthrough:
        enable: true
        delimiters:
          block: [['\[', '\]'], ['$$', '$$']]
          inline: [['\(', '\)']]
  highlight:
    noClasses: false

params:
  logo: icons/logo.svg
  offlineSearch: true
  offlineSearchIndex: summary
  offlineSearchMaxResults: 10
  github_repo: https://github.com/example/product-docs
  github_branch: main
  copyright:
    authors: '[Example Authors](https://example.org/)'
    from_year: 2026
  footer_center_info: 'Powered by [Oink](https://oink.pgsty.com)'
  ui:
    showLightDarkModeMenu: true
    quick_links: [docs, blog]
    sidebar_menu_foldable: true
    sidebar_item_overflow: wrap
    breadcrumb_disable: false

module:
  imports:
    - path: github.com/pgsty/oink
  hugoVersion:
    extended: true
    min: 0.160.1

The module version is pinned in the site’s go.mod. A conventional theme checkout can instead use theme: oink with the repository under themes/oink/.

Languages

defaultContentLanguage determines the unprefixed primary site. Language weight controls the visible order. label is the language’s self-name, and locale supplies the full HTML and SEO locale. Add languageDirection: rtl to an RTL language.

File naming

For the colocated model used by this site:

TEXT
content/docs/guide.md
content/docs/guide.zh.md

Files with the same base name are translations. Keep their logical page identity aligned. OINK reads Hugo’s translation relationships; it does not guess from arbitrary URL patterns.

Selector states

The selector needs no mode parameter. It is hidden for one configured language. With two or more, clicking the language icon advances to the next language by weight; hovering for half a second or focusing it opens the complete menu.

If the current page lacks a target translation, the target-language home page is used. Do not add dead page-shaped URLs merely to keep the selector on the same path.

Brand and repository

Set the site and per-language title and description. params.logo can point to a Hugo Asset or a path under static/. Keep favicons and social images in the documented asset locations.

Repository metadata drives “edit this page,” issue, and last-modified links:

YAML
params:
  github_repo: https://github.com/example/product-docs
  github_project_repo: https://github.com/example/product
  github_branch: main
  github_subdir: site

github_project_repo defaults to github_repo where supported. github_subdir is the content site’s path inside a monorepo. Keep github_branch resolvable; a display version is not necessarily a Git ref.

Use params.wordmark for a horizontal brand asset that should appear in the navbar, the sidebar drawer, and the footer. It accepts the same asset and static/ paths as params.logo. The compact navbar falls back to params.logo on its own, because a wordmark would consume the whole row; if wordmark is absent entirely, OINK keeps the existing logo-and-title treatment:

YAML
params:
  logo: images/product-mark.svg
  wordmark: images/product-wordmark.svg

OINK retains Docsy menus and UI parameters and adds focused shell controls:

YAML
params:
  page_width: normal
  ui:
    navbar_enabled: true
    footer_style: fat # fat | slim | none
    quick_links: [docs, blog]
    sidebar_width_min: 220
    sidebar_width_max: 480
    sidebar_item_overflow: wrap
    sidebar_menu_compact: true
    sidebar_menu_foldable: true
    sidebar_root_enabled: true
    sidebar_root_menu: true
    sidebar_search_disable: false
    breadcrumb_disable: false
    showLightDarkModeMenu: true
    taxonomy_icons:
      categories: fa-solid fa-folder
      tags: fa-solid fa-tags
    page_context_menu:
      enable: true
      assistant_links: false
      links: []
    readingtime:
      enable: true

navbar_enabled and footer_style decide whether each page carries the site navbar and which footer shape it uses. Both default to on (true and fat), apply to every layout, and can be overridden per section through a cascade or per page in front matter; an unknown footer_style fails the build. See Navigation and menus and Site footer.

page_width accepts normal, wide, or full and can be overridden in page front matter. Sidebar minimum and maximum values are pixels used to clamp the desktop drag resizer. sidebar_item_overflow: wrap wraps long labels; other values retain the compact ellipsis behavior.

quick_links names top-level page references shown by the shell. Define their translated names in each language’s main menu. taxonomy_icons sets the right-rail group icon per plural taxonomy name, defaulting to a folder for categories, tags for tags, and a generic shape elsewhere.

The page actions are a split button in the breadcrumb row: the primary half copies the page’s Markdown, and its menu keeps Copy Markdown, the assistant links, View markdown, View edit history, Edit this page, Create child page, the documentation and project issues, and Print entire section reachable at every viewport width. Built-in Open in ChatGPT / Claude actions are disabled by default. Set assistant_links: true to show them on file-backed pages; when a reader activates one, the full current URL — including its query string and fragment — leaves the site inside a localized prompt. Oink does not upload the page body. Avoid secrets in URLs and disclose this third-party boundary. A page can override the site policy with boolean assistant_links front matter.

View edit history appears when github_repo can resolve the same repository path used by Edit this page. links is empty by default. Additional custom links accept URL-encoded {url}, {title}, and {markdown_url} placeholders:

YAML
params:
  ui:
    page_context_menu:
      enable: true
      assistant_links: true
      links: []
      # - name: Ask an external assistant
      #   icon: fa-solid fa-wand-magic-sparkles
      #   url: https://assistant.example/new?source={markdown_url}&title={title}

Homepage content lives in data/home/<language>.yaml, with English used as the fallback. Each language file contains named data blocks and an optional sections list that composes those blocks into the exact landing-page order. The site footer is no longer part of that file — it now renders on every layout and reads data/footer/<language>.yaml. See Site footer.

Compose sections

A string entry uses the same value as its section type and data key. A map entry can select a built-in type, read a differently named key, set a stable id, or temporarily set enabled: false:

YAML
sections:
  - hero
  - metrics
  - capabilities
  - type: logo-wall
    key: ecosystem
  - gallery
  - faq
  - cta

ecosystem:
  title: Built with familiar tools
  columns: 4
  items:
    - {
        name: Hugo,
        icon: fa-solid fa-bolt,
        url: https://gohugo.io/,
        external: true,
      }

Map entries may also carry their content in data, which is useful for a short one-off block. Reuse a built-in type with different keys when two sections need the same presentation. A site-owned layout can name an explicit partial, but that is a custom template contract rather than portable homepage data.

If sections is absent, OINK preserves the 0.1.x order by rendering the blocks that exist among hero, metrics, capabilities, principles, and cta. Adding sections opts into explicit composition; omitted blocks then stay out of the page even if their data remains in the file.

Built-in sections

OINK 0.4.0 provides 21 section types:

Type Use it for
hero Primary message, actions, and theme-aware artwork
metrics Compact facts, numbers, links, and supporting text
capabilities Alternating feature narratives and specialist visual panels
principles Numbered product or operating principles
cards Generic feature, benefit, service, or path collections
logo-wall Tools, integrations, partners, or project lineage
gallery Screenshots or icon-led examples with badges and actions
testimonials Quotations with optional attribution and source links
contributors People, roles, avatars, and profile links
faq Native disclosure controls with Markdown answers
markdown Free-form prose when no collection layout is appropriate
cta One final action or a compact group of actions
pricing Product tiers, prices, features, and calls to action
pricing-compare Feature comparison matrices across pricing tiers
command-box A focused command with Copy support and an optional note
steps Ordered procedures with optional command examples
timeline Dated milestones, roadmaps, and release histories
code-plate Static code or line arrays in a presentation panel
case-study Evidence-led stories with metrics, quotation, and source
download Validated rolling and pinned download channels
bar-chart Comparable non-negative values rendered without chart JS

The homepage and regular layout: landing pages use the same registry. See Landing pages for data resolution, the nine scenario-oriented section contracts, no-JavaScript behavior, and output rules.

Common collection blocks accept eyebrow, title, desc or text, columns, and items. Item fields vary by presentation but consistently use title or name, desc or text, icon, image, url, and external. Ordinary text fields render Markdown. Keep internal URLs relative to the language root; set external: true for links that should open as external navigation.

Every block is optional, so a site can keep a short landing page without copying the layout. For example:

YAML
hero:
  eyebrow: Local-first documentation
  title_lines:
    - words:
        - { mark: P, text: roduct, color: red }
        - { mark: D, text: ocs, color: blue }
  lead: Documentation built and served with Hugo.
  image:
    light: images/hero-light.webp
    dark: images/hero-dark.webp
    alt: Product documentation workflow
  actions:
    - {
        label: Read the docs,
        url: docs/,
        icon: fa-solid fa-book,
        style: primary,
      }

The optional hero.image block adds a theme-aware visual on the right. Set light and dark to files under the site’s static/ directory; the active image follows the color-theme selector. If only src, light, or dark is provided, OINK uses that image for both themes. A string value is also accepted as a shared image. Omit image to keep the text-only Hero.

Below the landing sections, every page ends with the same site footer: the column grid when footer_style is fat, then the bottom bar. Its left side retains Docsy’s params.copyright API: use a Markdown string or a map with authors, from_year, and to_year; when omitted, Hugo’s top-level copyright value is rendered as-is. OINK’s params.footer_center_info accepts inline Markdown, defaults to Powered by Oink, and can be set to an empty string to hide the center region. The right side contains the language controls.

A site that still keeps a footer block in data/home/<language>.yaml is read as before, but that data now feeds the footer on every page rather than the homepage alone. Move it to data/footer/<language>.yaml when convenient.

Linked capability boards

A capability row can turn its component board into a compact navigator. Add a url to each linked item, name the region with aria_label, and choose one to four columns. Items without a URL remain decorative, so existing boards keep their current behavior:

YAML
capabilities:
  items:
    - title: Content on demand
      visual:
        type: components
        aria_label: Browse content components
        columns: 3
        compact: true
        items:
          - {
              title: Asciinema,
              icon: fa-solid fa-terminal,
              url: docs/components/layout/#asciinema,
            }
          - {
              title: Mermaid,
              icon: fa-solid fa-share-nodes,
              url: docs/components/diagrams/#diagrams-with-mermaid,
            }

The project site enables local search by default:

YAML
params:
  offlineSearch: true
  offlineSearchIndex: summary
  offlineSearchSummaryLength: 70
  offlineSearchMaxResults: 10

offlineSearchIndex controls how much text is downloadable in each language’s index. The scopes are cumulative: title indexes titles and taxonomy metadata; heading adds page headings; summary adds descriptions or summaries; and content also adds the complete body. content is the compatibility default, while summary is a smaller starting point for most documentation sites. offlineSearchMaxResults applies to both Lunr and the CJK substring fallback.

Each language receives a distinct index. Hosted alternatives remain supported through their established Docsy settings, but enabling them intentionally adds an external service boundary. Do not configure several competing search providers without also deciding which UI should be visible.

Content runtimes

Browser-only runtimes

Mermaid and KaTeX are detected from content. Enable Markmap at the site level:

YAML
params:
  markmap:
    enable: true
  mermaid:
    theme: default

Swagger UI, Redoc, Asciinema, ECharts, Infographic, and carousel assets load when their shortcodes appear. Their local runtime paths are internal and should not be configured.

Service endpoints

PlantUML and Diagrams.net require explicit endpoints:

YAML
params:
  plantuml:
    enable: true
    svg: true
    svg_image_url: https://diagrams.internal.example/plantuml/svg/
  drawio:
    enable: true
    drawio_server: https://diagrams.internal.example/

Leave the features disabled in an air-gap site unless those URLs are reachable inside the isolated network.

Page-level overrides

Hugo’s .Param lookup allows many site parameters to be overridden in front matter:

YAML
---
title: Wide reference
page_width: wide
navbar_enabled: false
footer_style: slim
hide_feedback: true
hide_readingtime: true
ui:
  no_left_sidebar: false
  scrollSpy:
    disable: false
---

navbar_enabled and footer_style are read from front matter directly, not from a ui block, so a section can set them once in its cascade.

Use overrides for real content differences, not to reconstruct a separate visual system page by page.

Avoid false configuration

Do not expose:

  • a switch between “Docsy” and “OINK” shells;
  • paths to vendored JavaScript, CSS, fonts, or internal partials;
  • duplicated language or repository values under a brand namespace;
  • toggles that merely select one of two copied implementations.

If a site needs a custom product matrix or portal, keep that component in the site and use a narrow hook or shortcode. A local business feature is clearer than a misleading global theme option.

Validate changes

After changing configuration:

  1. build with the minimum supported Hugo Extended version and the current validation version;
  2. test every configured language and one page without a translation;
  3. verify root and subpath baseURL output if both are supported;
  4. inspect local search and optional runtime requests;
  5. check the desktop and mobile shell, dark and light themes, and print output.

An accepted configuration is one that builds and behaves correctly, not merely one that parses as YAML.