Spaceboy Theme: Configuration Reference
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: seriffont: 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: trueBest 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: trueUse 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: docsviewMode 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 layoutsnormal (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"Lightbox (Image Zoom)
When enabled, every image in the post gets click-to-zoom via Fancybox. No need to manually add data-fancybox attributes.
lightbox: trueFull-Bleed Images
Stretches every image inside post-content to viewport width, breaking out of the content column.
imageFullBleed: truecontentWidth: 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 visiblePost Meta
Reading Progress Bar
A 3px bar at the top of the viewport that fills as you scroll. No layout impact.
progressBar: trueReading Time
Shows “X min read” in the post meta line. Hugo estimates ~200 words/minute.
showReadingTime: trueLast Modified Date
Appears only when lastmod differs from date — ideal for docs and tutorials that get updated.
showLastModified: truedate: 2026-01-15
lastmod: 2026-05-29Numbered Headings
Prepends 1., 1.1, 1.1.1 counters to h2, h3, h4 via CSS. No content changes needed.
numberedHeadings: trueHide Meta Block
Removes the entire date/author/reading-time line — useful for poems, untitled pieces, and any post where publication metadata feels intrusive.
noMeta: trueHide 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: falseHide Footer Block
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: trueSet 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: trueFooter 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: trueColor Scheme
Named colour palettes that override light and dark mode colours simultaneously. Does not change layout, fonts, or spacing — only CSS custom properties.
viewMode: NeonAvailable 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: trueThumbnail in Catalog View
Same as above but for the grid (catalog) view — image becomes the card background with a dim overlay.
showThumbnailInCatalog: trueExplicit 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: trueOverrides the auto-extraction completely. Useful when the first in-post image isn’t suitable as a card thumbnail.
Table of Contents
showToc: trueActivates 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.
Clicking a TOC link smooth-scrolls the heading to just below the sticky header — the same scroll-margin-top: 90px offset used by native #hash jumps, so the heading is never buried at the vertical center of the viewport. The active highlight is applied once the scroll completes, so the sidebar tracks the clicked heading correctly when navigating in either direction (e.g. jumping from the last section back to an earlier one).
Configure the sidebar labels in hugo.toml:
[params]
tocTitle = "Contents" # left sidebar header
tocSubTitle = "In this section" # right sidebar headerHR 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 valueShortcodes
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 >}}
git reset --hard discards all uncommitted changes permanently.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 >}}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:
- Write
$...$or$$...$$in your post - Run
npm run build:diagrams— updatesdata/katex-cache.json - 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:
- Add a
```mermaidblock to your post - Run
npm run build:diagrams— renders SVGs intostatic/mermaid-cache/ - 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: truesearchExclude
Excludes the page from /index.json — the site’s search index. It won’t show up in the search modal.
searchExclude: trueConfigurations 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.
Reading List / Link Log
---
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 homepageAuthor
[params.author]
name = "Your Name" # displayed in post metaHead Title
headTitle = "My Blog" # text shown in the site header link (defaults to author name, then site title)Navigation
[[params.nav]]
name = "Home"
link = "/"
[[params.nav]]
name = "About"
link = "/about"Social Links
[[params.socials]]
name = "GitHub"
link = "https://github.com/username"
[[params.socials]]
name = "RSS"
link = "/index.xml"Supported icon names: GitHub, Twitter, LinkedIn, RSS, Email.
Footer Links
[[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"
enableTableResize = true # drag table column dividers + bottom row-height handleTable resizing is session-only and rides on the table’s own borders — no extra handles. Hover a column separator in the header row and the gridline lights up: drag it to widen/narrow columns (neighbours absorb the delta, so the total width holds). Hover the table’s bottom edge and the border lights up: drag down to add vertical space inside every row, or up to remove it. Keyboard: tab to a separator and use ←/→ (columns) or ↑/↓ (rows), holding Shift for larger steps; Esc cancels an in-progress drag. Reloading the page restores the natural layout.
Search
Client-side search powered by Fuse.js. Press Ctrl+K (or the search icon in the header) to open the modal.
enableSearch = true # show search button + modal (default: true)
fuseJSLocal = "" # self-hosted Fuse.js path under static/
fuseJSCDN = "https://cdn.jsdelivr.net/npm/fuse.js@7.0.0/dist/fuse.min.js"
fuseJSCDNIntegrity = "" # optional SRI hash for the CDN script- Search is lazy: Fuse.js and
/index.jsonload on the first keystroke, not on page load. - Idle state: with an empty query the modal shows the 5 most recent posts, server-rendered by Hugo (no extra requests, no Fuse needed). They’re navigable with
↑↓/↵and clickable. Typing replaces them with live results; clearing the input restores them. - The search index is the site’s
/index.json(prefixed bystaticPrefixif set). Exclude a page from it withsearchExclude: true(see searchExclude). legacyMode: truedisables search entirely.
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 booleanStatic Files
staticPrefix = "" # CDN prefix for RSS and local vendor files
extraCSSFiles = ["css/custom.css"] # additional CSS files to bundleKaTeX / 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/.