Every parameter can be set in two places. hugo.toml [params] sets the site-wide default. Front matter on a single post overrides it. Front matter always wins.

Typography

Font Family

The font parameter replaces --font-body for the entire page — headings, nav, and body text.

By default (no font parameter), --font-body uses Atkinson Hyperlegible (Google Fonts), a highly-legible sans-serif designed for low-vision readers.

Value Renders as Best for
(none) Atkinson Hyperlegible (default) General reading, accessibility
mono JetBrains Mono Tech posts, code-heavy writing
serif Georgia → Charter → Palatino Stories, novels, essays, research
sans system-ui → Segoe UI → Roboto Short-form, recipes, reviews
any CSS string Custom font stack Total control
font: serif
Note
font: serif also sets --letter-spacing-normal: 0.01em and --line-height-body: 1.9 automatically — both improve serif body readability without any extra config.

Drop Cap

Enlarges the first letter of the first paragraph using CSS ::first-letter. No markup changes needed.

dropCap: true

Best paired with font: serif and contentWidth: normal.

Justified Text

Applies text-align: justify with automatic hyphenation to paragraphs only. Headings and blockquotes stay left-aligned.

justify: true

Use for essays, formal writing, or long-form prose where you want the clean block-edge look.

Opening Epigraph

A centred italic quote rendered before the post body. Set directly in front matter for a simple string:

epigraph: "Not one of these dreams has fulfilled me, nor have I expected them to."

For author attribution use the {{< epigraph >}} shortcode instead — see Shortcodes.

ViewMode (presets)

Bundles font, layout, and meta display into a single param. Individual params still override.

Mode Font Best for
docs Atkinson (default) Tutorials, reference, code-heavy posts, papers
poem Atkinson (default) Poetry (centred text)
goofy Atkinson (default) Distraction-free reading, big fonts, no chrome
minimal Atkinson (default) No footer, wide layout — scratch pads, unlisted pages

Removed modes: prose → use font: serif; list → use font: sans; news → use research + font: sans.

viewMode: docs
Note
viewMode sets CSS and template defaults. Explicit font, contentWidth, showToc, etc. always beat the mode.

Layout

Content Width

contentWidth: normal   # clamp(320px, 95vw, 1200px) — default, good for most posts
contentWidth: wide     # clamp(320px, 95vw, calc((1200px + 100vw)/2)) — between normal and full
contentWidth: full     # 100% — comics, photography, full-bleed layouts
Prose tip
normal (clamp up to 1200px) is a comfortable reading width. For even more space use wide.

Cover Image

A full-width hero image shown at the top of the post, above the title. Also used as og:image for social sharing.

coverImage: "https://example.com/my-header-image.jpg"

When enabled, every image in the post gets click-to-zoom via Fancybox. No need to manually add data-fancybox attributes.

lightbox: true

Full-Bleed Images

Stretches every image inside post-content to viewport width, breaking out of the content column.

imageFullBleed: true
Warning
Works best with contentWidth: full and showToc: false. In the three-column TOC layout the grid clips the bleed.

Code Block Height

The default max-height for code blocks is 32rem — beyond that the block scrolls. Override or remove the limit:

codeMaxHeight: "50rem"   # taller blocks
codeMaxHeight: "none"    # no limit, full code always visible

Post Meta

Reading Progress Bar

A 3px bar at the top of the viewport that fills as you scroll. No layout impact.

progressBar: true

Reading Time

Shows “X min read” in the post meta line. Hugo estimates ~200 words/minute.

showReadingTime: true

Last Modified Date

Appears only when lastmod differs from date — ideal for docs and tutorials that get updated.

showLastModified: true
date: 2026-01-15
lastmod: 2026-05-29

Numbered Headings

Prepends 1., 1.1, 1.1.1 counters to h2, h3, h4 via CSS. No content changes needed.

numberedHeadings: true

Hide Meta Block

Removes the entire date/author/reading-time line — useful for poems, untitled pieces, and any post where publication metadata feels intrusive.

noMeta: true

Hide Post Title

Suppresses the <h1> rendered from the title: front matter field. Use when providing a decorative title inside the post body via the {{< chapter >}} shortcode.

show-title: false

Removes tags, related posts, ads, and comments from the bottom of the page. Useful for poems, visual essays, and pages where post-footprint content feels cluttered.

hideFooter: true

Set automatically by viewMode: goofy, media, and poem.

Granular Section Toggles

Fine-grained control over individual meta and footer elements. Each defaults to respecting the parent flag (noMeta / hideFooter), but can be set independently.

Meta toggles (beat noMeta):

Param Default What it controls
showDate not $noMeta Publish date in meta
showAuthor not $noMeta Author name in meta
showWordCount not $noMeta Word count in meta
showDate: false      # hide date, keep author and word count
showAuthor: true
showWordCount: true

Footer toggles (beat hideFooter):

Param Default What it controls
showTags not $hideFooter Tags section
showShare not $hideFooter Social share buttons
showRelatedPosts not $hideFooter Related posts section
showPostNav not $hideFooter Prev/next navigation
showComments not $hideFooter Comments section
showShare: false      # hide only share buttons, keep everything else
showRelatedPosts: false
showTags: true
showPostNav: true

Color Scheme

Named colour palettes that override light and dark mode colours simultaneously. Does not change layout, fonts, or spacing — only CSS custom properties.

viewMode: Neon

Available schemes: 90s, Modern, Neon, Anime, Maharaja, Nature, Galaxy, Ocean, BlackWhite, C-Looney-Tunes, C-Disney, Hacker, 2d-game.

The per-page author.homepage param wraps the author name in a hyperlink in the post meta line. Falls back to plain text when unset.

author:
  homepage: "https://example.com"

Abstract Block

A left-bordered italic block rendered before the body text. For research papers and technical reports.

abstract: "One paragraph summary of what this post covers and why it matters."

Thumbnail in List View

Shows a thumbnail in list view (hamburger toggle on homepage), with a dim overlay so text stays readable.

showThumbnailInList: true

Thumbnail in Catalog View

Same as above but for the grid (catalog) view — image becomes the card background with a dim overlay.

showThumbnailInCatalog: true

Explicit Thumbnail URL

By default the thumbnail is auto-extracted from the first markdown image in the post. Use thumbnail to set a specific URL instead:

thumbnail: /images/my-custom-thumb.webp
showThumbnailInList: true

Overrides the auto-extraction completely. Useful when the first in-post image isn’t suitable as a card thumbnail.

Table of Contents

showToc: true

Activates the three-column layout: left sidebar (full chapter overview), main content, right sidebar (sub-sections of the current section). On screens below 768px both sidebars hide and a toggle button appears above the content.

The right sidebar shows sub-headings under the active section. When those sub-headings are identical to what the left sidebar already shows (e.g. a post with only h2s and no h3s), the right sidebar displays “No sub headings” instead of repeating the same list.

Configure the sidebar labels in hugo.toml:

[params]
  tocTitle    = "Contents"        # left sidebar header
  tocSubTitle = "In this section" # right sidebar header

HR Separators

Controls how --- in Markdown renders.

hrStyle: small   # 4em centred line — scene breaks in fiction
hrStyle: full    # 100% width — section dividers in docs
hrStyle: 40%     # any CSS length value

Shortcodes

Callouts

Five variants: note, tip, warning, danger, info. All accept an optional title param.

{{< note >}} Information worth highlighting. {{< /note >}}
{{< tip title="Hint" >}} A helpful suggestion. {{< /tip >}}
{{< warning >}} Caution before proceeding. {{< /warning >}}
{{< danger >}} Potential data loss or breakage. {{< /danger >}}
{{< info >}} Neutral supplemental context. {{< /info >}}

Epigraph

A centred italic opening quote. Accepts author and source params.

{{< epigraph author="Le Guin" source="The Dispossessed" >}} There was a wall. {{< /epigraph >}}

For multi-line quotes, write the shortcode tags on their own lines. Hugo processes them correctly when the inner content is on a separate line.

Chapter Title

A decorative chapter heading. Use with show-title: false so the front matter title is suppressed.

{{< chapter number="Chapter Three" >}} The Long Way Home {{< /chapter >}}

Renders a small caps chapter label above the main title text.

Spoiler

A collapsible <details> block. Default label is “Spoiler — click to reveal”.

{{< spoiler title="What happens at the end" >}} The lighthouse was a metaphor all along. {{< /spoiler >}}

Poem

Centres and italicises the content. Use two trailing spaces at end of each line for line breaks; an empty line between stanzas.

{{< poem title="i." >}} last train — / window cracked — / smell of rain {{< /poem >}}

In actual use, write each line on its own with two trailing spaces:

{{< poem >}}
last train of the night —  
someone left a window cracked  
the smell of rain gets in
{{< /poem >}}
Note
The multi-line form above works fine in post content. The single-line form shown in code is just to avoid documentation rendering issues.

Details / Accordion

A collapsible block for supplemental content — ingredient lists, optional steps, extended notes.

{{< details title="Ingredients (serves 2)" >}} - 1½ cups rice / - 6 garlic cloves {{< /details >}}

Star Rating

Positional argument is the score; max is optional (defaults to 5).

{{< rating 8 10 >}}    →  ★★★★★★★★☆☆  8/10
{{< rating 4 5 >}}           →  ★★★★☆        4/5

Keyboard Keys

Inline keyboard key styling.

Press {{< kbd >}}Ctrl{{< /kbd >}} + {{< kbd >}}S{{< /kbd >}} to save.

Center

Wraps content in a centered <div>.

{{< center >}} This text will be centred. {{< /center >}}

KaTeX (Math)

Use $...$ for inline math and $$...$$ for display math directly in Markdown — no shortcode needed.

The sigmoid $f(x) = \frac{1}{1 + e^{-x}}$ maps any value to (0, 1).

$$
\sum_{k=1}^{n} k = \frac{n(n+1)}{2}
$$

Math is pre-rendered at build time — no KaTeX JS loads at runtime. After adding new expressions, run npm run build:diagrams and commit data/katex-cache.json.


Advanced Features

KaTeX (Math Rendering)

Math expressions ($...$ inline, $$...$$ block) are pre-rendered to HTML at build time via scripts/render-katex-cache.mjs. No KaTeX JS loads at runtime — only KaTeX CSS is needed for styling.

Build workflow:

  1. Write $...$ or $$...$$ in your post
  2. Run npm run build:diagrams — updates data/katex-cache.json
  3. Commit the updated cache file

Detection heuristic: inline $...$ is only treated as math if the content contains a LaTeX command (\frac, \sum, etc.) or ^/_. This avoids false positives from JavaScript $('selector') patterns.

Customise the KaTeX CSS CDN in hugo.toml:

[params]
  katexCSSCDN = "https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css"

Fancybox (Image Lightbox)

Every image in every post is automatically wrapped in a Fancybox lightbox link via the render-image hook. Click any image to open the full-resolution viewer with swipe/zoom. No config needed.

Customise CDN URLs in hugo.toml:

[params]
  fancyboxCSSCDN = "https://cdn.jsdelivr.net/npm/@fancyapps/ui@6.1/dist/fancybox/fancybox.css"
  fancyboxJSCDN  = "https://cdn.jsdelivr.net/npm/@fancyapps/ui@6.1/dist/fancybox/fancybox.umd.js"

Mermaid (Diagrams)

Render diagrams from text using fenced code blocks with ```mermaid:

```mermaid
graph TD
  A[Start] --> B{Choice}
  B -->|Yes| C[End]
  B -->|No| A
```

Diagrams are pre-rendered to SVGs at build time via scripts/render-mermaid-cache.mjs. No Mermaid JS loads at runtime. SVGs use CSS variables so they adapt to the active color palette automatically.

Build workflow:

  1. Add a ```mermaid block to your post
  2. Run npm run build:diagrams — renders SVGs into static/mermaid-cache/
  3. Commit the new SVG and the updated data/mermaid-manifest.json

Code Export

Code blocks (both regular and Mermaid) include an “Open as image” button alongside the copy button. Clicking it opens the block in a new window with options to download as SVG or PNG.


Per-Post Injections

Inject custom code into individual posts without touching theme files.

Custom CSS

Inline CSS injected in <head>, scoped to this page only.

customCSS: |
  .my-special-box {
    background: linear-gradient(135deg, #667eea, #764ba2);
    padding: 2rem;
    border-radius: 12px;
    color: white;
  }

Custom JS

Inline JavaScript injected before </body>.

customJS: |
  document.querySelectorAll('.my-special-box').forEach(function(el) {
    el.addEventListener('click', function() {
      alert('Clicked!');
    });
  });

Custom Head

Raw HTML injected in <head>. Useful for per-page meta tags, schema, fonts, or preloads.

customHead: |
  <meta name="theme-color" content="#667eea">
  <link rel="preload" href="/fonts/special.woff2" as="font" crossorigin>

SEO Controls

noindex

Adds <meta name="robots" content="noindex"> so search engines skip this page.

noindex: true

searchExclude

Excludes the page from /index.json — the site’s search index. It won’t show up in the search modal.

searchExclude: true

Configurations by Content Type

Complete front matter presets. Copy the block that matches your post type.

Story / Short Story

---
viewMode: goofy
---

Optionally add dropCap: true for the first-letter style.

Novel Chapter

---
viewMode: goofy
progressBar: true
show-title: false
---

Open the post body with the {{< chapter >}} and {{< epigraph >}} shortcodes to replace the suppressed front matter title.

Essay

---
viewMode: goofy
---

Research Paper

---
viewMode: docs
showLastModified: true
abstract: "One paragraph summary of the paper."
---

Use docs for papers, surveys, and research writing — enable showToc and justify explicitly if desired.

Technical Documentation

---
viewMode: docs
showLastModified: true
---

Use {{< note >}} / {{< tip >}} / {{< warning >}} / {{< danger >}} throughout.
Use {{< details >}} for optional or reference content.
Use {{< kbd >}} for keyboard shortcuts.

Tutorial (step-by-step)

---
viewMode: docs
---

Structure h2 headings as steps — ## 1. Install, ## 2. Configure, ## 3. Run.

Recipe

---
font: sans
---

Wrap the ingredient list in {{< details title="Ingredients" >}} so the page doesn’t open with a wall of text.

Review (book / anime / game)

---
font: sans
---

Use {{< rating 8 10 >}} for scores and {{< spoiler >}} for plot details.

Comic / Visual

Poem

---
viewMode: poem
show-title: false
---

Use {{< chapter >}} for the title and {{< poem >}} for each stanza group.

Devlog / Changelog

---
viewMode: docs
showLastModified: true
---

Structure with ## Week of YYYY-MM-DD or ## vX.Y.Z headings.

---
font: sans
---

Photo Essay

---
viewMode: minimal
coverImage: "https://..."
font: serif
---

Full Parameter Reference

---
title: "Post Title"
date: 2026-01-01
lastmod: 2026-05-29

# ── Typography ──────────────────────────────────
font: mono                # mono | serif | sans | CSS font-family string (default: Atkinson Hyperlegible sans-serif)
dropCap: false            # large first letter on first paragraph
justify: false            # justify paragraph text
epigraph: ""              # opening quote rendered before body

# ── ViewMode & Color ────────────────────────────
viewMode: ""               # docs | poem | goofy | minimal | <PaletteName>

# ── Layout ──────────────────────────────────────
contentWidth: normal      # normal | wide | full
coverImage: ""            # hero image URL (also sets og:image)
imageFullBleed: false     # stretch images to viewport width
lightbox: false           # enable click-to-zoom on all images
codeMaxHeight: "32rem"    # max-height of code blocks; "none" to remove

# ── Meta display ────────────────────────────────
progressBar: false
showReadingTime: false
showLastModified: false
noMeta: false             # hide the entire meta line (individual toggles below beat it)
show-title: true          # hide the h1 rendered from front matter title
showDate: true            # granular: show publish date (respects noMeta)
showAuthor: true          # granular: show author name (respects noMeta)
showWordCount: true       # granular: show word count (respects noMeta)

# ── Footer display ──────────────────────────────
hideFooter: false         # hide tags, share, related, comments, nav (individual toggles below beat it)
showTags: true            # show tags section (respects hideFooter)
showShare: true           # show social share buttons (respects hideFooter)
showRelatedPosts: true    # show related posts section (respects hideFooter)
showPostNav: true         # show prev/next navigation (respects hideFooter)
showComments: true        # show comments section (respects hideFooter)
author:
  homepage: ""            # wraps author name in a link when set

# ── Structure ───────────────────────────────────
showToc: false
numberedHeadings: false

# ── Content ─────────────────────────────────────
abstract: ""
hrStyle: small            # small | full | CSS length

# ── Per-post injections ────────────────────────
customCSS: ""             # inline CSS injected in <head>
customJS: ""              # inline JS injected before </body>
customHead: ""            # raw HTML injected in <head>

# ── SEO ─────────────────────────────────────────
noindex: false            # add <meta name="robots" content="noindex">
searchExclude: false      # exclude from /index.json search index
---

## Site-wide Configuration (`hugo.toml [params]`)

These are set in `hugo.toml` under `[params]` and apply across the entire site.

### Main Sections

```toml
mainSections = ["posts"]   # which content types appear on the homepage

Author

[params.author]
  name = "Your Name"       # displayed in post meta

Head Title

headTitle = "My Blog"      # text shown in the site header link (defaults to author name, then site title)
[[params.nav]]
  name = "Home"
  link = "/"
[[params.nav]]
  name = "About"
  link = "/about"
[[params.socials]]
  name = "GitHub"
  link = "https://github.com/username"
[[params.socials]]
  name = "RSS"
  link = "/index.xml"

Supported icon names: GitHub, Twitter, LinkedIn, RSS, Email.

[[params.footerLinks]]
  name = "Privacy"
  link = "/privacy"
[[params.footerLinks]]
  name = "Colophon"
  link = "/colophon"

Features

enableCopyCode = true      # show copy button on code blocks (default: true)
lazyImage = true           # lazy-load images (default: true)
showCategories = true      # show category links on homepage cards
enableCDNFallback = true   # use CDN for Fancybox/KaTeX when available
legacyMode = false         # disable all JS enhancements
showReadingTime = false    # global default for "X min read"

Content Injection

Raw HTML injected at specific points:

postHeaderContent = ""     # before .Content inside the post
postFooterContent = ""     # after .Content, before related posts
postAds = ""               # after related posts, before comments
extraHead = ""             # before </head>
extraBody = ""             # before </body>

Disqus

disqus = "your-shortname"  # string — NOT a boolean

Static Files

staticPrefix = ""          # CDN prefix for RSS and local vendor files
extraCSSFiles = ["css/custom.css"]   # additional CSS files to bundle

KaTeX / Fancybox CDN Overrides

# KaTeX CSS (still loaded for rendered math styling — no KaTeX JS at runtime)
katexCSSCDN = "https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css"

# Fancybox
fancyboxCSSCDN = "https://cdn.jsdelivr.net/npm/@fancyapps/ui@6.1/dist/fancybox/fancybox.css"
fancyboxJSCDN  = "https://cdn.jsdelivr.net/npm/@fancyapps/ui@6.1/dist/fancybox/fancybox.umd.js"

For self-hosted assets, append Local to the key (e.g. katexCSSLocal, fancyboxJSLocal) pointing to a path under static/.