Overview
Hugo v0.140+ introduced significant changes to template handling, JSON output, and theme architecture. This page documents proven patterns for automating documentation workflows with Hugo as the core engine, including Svelte 5 integration strategies.
Key Patterns
1. JSON Feed as API
Hugoβs custom output formats let you generate index.json for any section, turning your static site into a headless CMS:
[outputFormats.JSON]
mediaType = "application/json"
baseName = "index"
isPlainText = true
[outputs]
section = ["HTML", "RSS", "JSON"]Template (layouts/_default/list.json.json):
{{- $items := slice -}}
{{- range .Pages -}}
{{- $items = $items | append (dict
"title" .Title
"url" .RelPermalink
"summary" (.Summary | truncate 160)
"date" (.Date.Format "2006-01-02")
"tags" .Params.tags) -}}
{{- end -}}
{{- $items | jsonify -}}Critical: Use .RelPermalink not .Permalink β absolute URLs break when the domain differs between build and serve environments.
2. Zero-Build Dashboard Integration
Instead of a separate Svelte/Vite build, place a vanilla JS SPA at static/dashboard/index.html. Hugo copies static/ β public/ verbatim. The dashboard fetches /topics/index.json and renders cards client-side.
Benefits:
- No Node.js dependency in deploy pipeline
- Single
hugo --minifybuild step - Nginx serves everything statically
3. Svelte 5 + Hugo Hybrid Architecture
For interactive components, embed Svelte 5 as hydrated islands within Hugo pages:
content/
posts/
my-post.md # Hugo markdown
components/
Counter.svelte # Svelte 5 component
Build pipeline:
# 1. Build Svelte components to IIFE modules
vite build --mode ssg
# 2. Hugo builds markdown + copies Svelte assets
hugo --minify
# 3. Nginx serves bothHugo shortcode for Svelte islands:
<!-- layouts/shortcodes/svelte.html -->
<div id="svelte-{{ .Get 0 }}" data-props='{{ .Inner | jsonify }}'></div>
<script type="module">
import './components/{{ .Get 0 }}.js';
hydrate(App, { target: document.getElementById('svelte-{{ .Get 0 }}'), props: JSON.parse(document.getElementById('svelte-{{ .Get 0 }}').dataset.props) });
</script>Usage in markdown (shortcode):
{{%/* svelte "Counter" */%}}
{"initial": 5}
{{%/* /svelte */%}}4. Content Taxonomy vs Section
Gotcha: Declaring topic = "topics" in [taxonomies] makes content/topics/ a taxonomy, not a section. Section-level index.json wonβt generate.
# CORRECT β tags only, topics is a section
[taxonomies]
tag = "tags"
# WRONG β breaks section JSON output
[taxonomies]
tag = "tags"
topic = "topics"5. Front Matter Tag Arrays
Tags must be proper YAML arrays. Comma-separated strings become a single tag:
# CORRECT
tags: ["hugo", "automation", "docs", "svelte5"]
# WRONG β becomes one tag "hugo, automation, docs, svelte5"
tags: ["hugo, automation, docs, svelte5"]6. Hugo 0.140 Template Changes
$.IsMenuand$currentPage.IsMenuremoved β use simple nav loops without active-state detection.Site.RegularPagesin section templates shows ALL pages β use.Pagesfor section-scoped listing- JSON templates with
.json.jsonextension are flagged by linters as invalid JSON β this is a false positive; these are Hugo templates
Svelte 5 Integration Patterns
Pattern A: Vanilla JS Dashboard (Zero Build)
- Current LLM-Wiki approach
- No Svelte dependency in production
- Best for: read-only dashboards, search, filtering
Pattern B: Svelte 5 Islands (Partial Hydration)
- Hugo renders static content
- Svelte 5 hydrates interactive widgets
- Best for: calculators, forms, real-time widgets
Pattern C: SvelteKit + Hugo Hybrid
- SvelteKit for app routes
- Hugo for content routes
- Shared component library
- Best for: full apps with documentation
Automation Pipeline
research-automation.py β content/topics/*.md β hugo build β public/topics/index.json β dashboard
- Research script generates/updates markdown with proper front matter
- Hugo builds HTML + JSON output
- Dashboard fetches JSON, renders searchable card grid
- Deploy:
hugo --minify && sudo nginx -t && sudo systemctl reload nginx
Svelte 5 Component Structure for Hugo
hugo-llm-wiki/
βββ static/
β βββ components/ # Built Svelte 5 components (IIFE)
β βββ Counter.js
β βββ SearchWidget.js
βββ components/ # Source Svelte 5 components
β βββ Counter.svelte
β βββ SearchWidget.svelte
βββ vite.config.ssg.ts # Vite config for SSG build
βββ layouts/shortcodes/
βββ svelte.html # Hugo shortcode
vite.config.ssg.ts:
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
plugins: [svelte({ compilerOptions: { runes: true } })],
build: {
lib: {
entry: 'components/index.ts',
formats: ['iife'],
name: 'SvelteComponents'
},
outDir: '../static/components'
}
});Related Topics
- Svelte 5 Best Practices
- Svelte 5 Migration Guide
- LLM-Powered Knowledge Bases
- Self-Discovering Documentation
- AI Content Evolution
Evolution Notes
Content last updated: 2026-06-05 Next review: 2026-06-12