hugo
Hugo Static Site Generator
Status: Production Ready Last Updated: 2025-11-04 Dependencies: None (Hugo is a standalone binary) Latest Versions: hugo@0.152.2+extended, PaperMod@latest, Sveltia CMS@latest
Quick Start (5 Minutes)
1. Install Hugo Extended
CRITICAL: Always install Hugo Extended edition (not Standard) unless you're certain you don't need SCSS/Sass support. Most themes require Extended.
# macOS
brew install hugo
# Linux (Ubuntu/Debian)
wget https://github.com/gohugoio/hugo/releases/download/v0.152.2/hugo_extended_0.152.2_linux-amd64.deb
sudo dpkg -i hugo_extended_0.152.2_linux-amd64.deb
# Verify Extended edition
hugo version # Should show "+extended"
Why this matters:
- Hugo Extended includes SCSS/Sass processing
- Most popular themes (PaperMod, Academic, Docsy) require Extended
- Standard edition will fail with "SCSS support not enabled" errors
- Extended has no downsides (same speed, same features + more)
2. Create New Hugo Site
# Use YAML format (not TOML) for better CMS compatibility
hugo new site my-blog --format yaml
# Initialize Git
cd my-blog
git init
# Add PaperMod theme (recommended for blogs)
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
CRITICAL:
- Use
--format yamlto create hugo.yaml (not hugo.toml) - YAML is required for Sveltia CMS and recommended for TinaCMS
- TOML has known bugs in Sveltia CMS beta
- Git submodules require
--recursiveflag when cloning later
3. Configure and Build
# hugo.yaml - Minimal working configuration
baseURL: "https://example.com/"
title: "My Hugo Blog"
theme: "PaperMod"
languageCode: "en-us"
enableRobotsTXT: true
params:
ShowReadingTime: true
ShowShareButtons: true
defaultTheme: auto # Supports dark/light/auto
# Create first post
hugo new content posts/first-post.md
# Run development server (with live reload)
hugo server
# Build for production
hugo --minify
# Output is in public/ directory
The 7-Step Setup Process
Step 1: Installation and Verification
Install Hugo Extended using one of these methods:
Method 1: Homebrew (macOS/Linux) ✅ Recommended
brew install hugo
Method 2: Binary Download (Linux)
# Check latest version: https://github.com/gohugoio/hugo/releases
VERSION="0.152.2"
wget https://github.com/gohugoio/hugo/releases/download/v${VERSION}/hugo_extended_${VERSION}_linux-amd64.deb
sudo dpkg -i hugo_extended_${VERSION}_linux-amd64.deb
Method 3: Docker
docker run --rm -it -v $(pwd):/src klakegg/hugo:ext-alpine
Method 4: NPM Wrapper (not recommended, may lag behind)
npm install -g hugo-bin
Verification:
hugo version
# Should output: hugo v0.152.2+extended
# ^^^^^^^^ Must show "+extended"
Key Points:
- Extended edition required for SCSS/Sass
- Version should be v0.149.0+ for best compatibility
- NPM wrapper may be behind official releases
- Pin version in CI/CD (see Step 7)
Step 2: Project Scaffolding
Create new site with YAML configuration:
hugo new site my-site --format yaml
cd my-site
Directory structure created:
my-site/
├── hugo.yaml # Configuration (YAML format)
├── archetypes/ # Content templates
│ └── default.md
├── content/ # All your content goes here
├── data/ # Data files (JSON/YAML/TOML)
├── layouts/ # Template overrides
├── static/ # Static assets (images, CSS, JS)
├── themes/ # Themes directory
└── public/ # Build output (generated, git ignore)
CRITICAL:
- Use
--format yamlfor CMS compatibility - Never commit
public/directory to Git - Create
.gitignoreimmediately (see Step 3)
Step 3: Theme Installation
Recommended Method: Git Submodule ✅
# Popular themes:
# - PaperMod (blogs): https://github.com/adityatelange/hugo-PaperMod
# - Book (docs): https://github.com/alex-shpak/hugo-book
# - Academic (research): https://github.com/HugoBlox/theme-academic-cv
# - Ananke (general): https://github.com/theNewDynamic/gohugo-theme-ananke
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
Alternative: Hugo Modules (advanced)
hugo mod init github.com/username/my-site
# In hugo.yaml:
# module:
# imports:
# - path: github.com/adityatelange/hugo-PaperMod
Add theme to hugo.yaml:
theme: "PaperMod"
When cloning project with submodules:
git clone --recursive https://github.com/username/my-site.git
# Or if already cloned:
git submodule update --init --recursive
Key Points:
- Git submodules are recommended over manual downloads
--depth=1saves space (no theme history)- Always run
git submodule update --init --recursiveafter clone - Hugo Modules are more advanced but don't require Git submodules
Step 4: Configuration
hugo.yaml - Complete Example (PaperMod blog):
baseURL: "https://example.com/"
title: "My Hugo Blog"
theme: "PaperMod"
languageCode: "en-us"
defaultContentLanguage: "en"
enableRobotsTXT: true
buildDrafts: false
buildFuture: false
buildExpired: false
enableEmoji: true
minify:
disableXML: true
minifyOutput: true
params:
env: production
title: "My Hugo Blog"
description: "A blog built with Hugo and PaperMod"
author: "Your Name"
ShowReadingTime: true
ShowShareButtons: true
ShowPostNavLinks: true
ShowBreadCrumbs: true
ShowCodeCopyButtons: true
defaultTheme: auto # dark, light, auto
socialIcons:
- name: twitter
url: "https://twitter.com/username"
- name: github
url: "https://github.com/username"
menu:
main:
- identifier: posts
name: Posts
url: /posts/
weight: 10
- identifier: about
name: About
url: /about/
weight: 20
outputs:
home:
- HTML
- RSS
- JSON # Required for search
Configuration Formats:
- YAML (recommended):
hugo.yaml- Better CMS compatibility - TOML (legacy):
hugo.toml- Default but problematic with Sveltia CMS - JSON:
hugo.json- Rarely used
Environment-Specific Configs:
config/
├── _default/
│ └── hugo.yaml
├── production/
│ └── hugo.yaml # Overrides for production
└── development/
└── hugo.yaml # Overrides for local dev
Step 5: Content Creation
Create content with Hugo CLI:
# Blog post
hugo new content posts/my-first-post.md
# Page
hugo new content about.md
# Nested documentation
hugo new content docs/getting-started/installation.md
Frontmatter Format (YAML recommended):
---
title: "My First Post"
date: 2025-11-04T10:00:00+11:00
draft: false
tags: ["hugo", "blog"]
categories: ["General"]
description: "A brief description for SEO"
cover:
image: "/images/cover.jpg"
alt: "Cover image"
---
# Post content starts here
This is my first Hugo blog post!
TOML Frontmatter (for reference only):
+++
title = "My First Post"
date = 2025-11-04T10:00:00+11:00
draft = false
tags = ["hugo", "blog"]
+++
Key Points:
- Use
---delimiters for YAML frontmatter - Use
+++delimiters for TOML frontmatter draft: falserequired for post to appear in productiondatein future = post won't publish (unless--buildFutureflag used)- Content goes after frontmatter closing delimiter
Step 6: Build and Development
Development server (with live reload):
# Start server
hugo server
# With drafts visible
hugo server --buildDrafts
# With future-dated posts
hugo server --buildFuture
# Bind to specific port
hugo server --port 1314
# Access at: http://localhost:1313
Production build:
# Basic build
hugo
# With minification (recommended)
hugo --minify
# With specific baseURL (for deployment)
hugo --minify --baseURL https://example.com
# Or use environment variable
hugo --minify -b $CF_PAGES_URL
Build Output:
- All generated files go to
public/directory - Typical build time: <100ms for small sites, <5s for 1000+ pages
- Hugo is the fastest static site generator
Key Points:
- Development server has live reload (HMR)
- Production build should use
--minify - Never commit
public/directory - Build time is extremely fast (Hugo is written in Go)
Step 7: Cloudflare Workers Deployment
Create wrangler.jsonc:
{
"name": "my-hugo-site",
"compatibility_date": "2025-01-29",
"assets": {
"directory": "./public",
"html_handling": "auto-trailing-slash",
"not_found_handling": "404-page"
}
}
Manual deployment:
# Build site
hugo --minify
# Deploy to Workers
npx wrangler deploy
GitHub Actions (Automated):
Create .github/workflows/deploy.yml:
name: Deploy to Cloudflare Workers
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive # Important for theme submodules!
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.152.2'
extended: true
- name: Build
run: hugo --minify
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
Key Points:
assets.directorymust be"./public"(Hugo's output)html_handling: "auto-trailing-slash"handles Hugo's URL structurenot_found_handling: "404-page"serves Hugo's 404.html- Always pin Hugo version in CI/CD (prevents version mismatch errors)
- Use
submodules: recursivefor theme submodules
Critical Rules
Always Do
✅ Install Hugo Extended (not Standard) - required for SCSS/Sass support in themes
✅ Use YAML configuration (--format yaml) - better CMS compatibility than TOML
✅ Add themes as Git submodules - easier updates and version control
✅ Set correct baseURL - prevents broken asset links on deployment
✅ Pin Hugo version in CI/CD - prevents version mismatch errors between local and deployment
✅ Add public/ to .gitignore - build output should not be committed
✅ Use draft: false - drafts don't appear in production builds
✅ Clone with --recursive flag - ensures theme submodules are fetched
✅ Use relative paths for images - /images/photo.jpg not ../images/photo.jpg
✅ Test build before deploying - catch errors locally with hugo --minify
Never Do
❌ Don't install Hugo Standard - most themes require Extended edition
❌ Don't use TOML config with Sveltia CMS - has known bugs, use YAML instead
❌ Don't commit public/ directory - it's generated output, not source code
❌ Don't use different Hugo versions - local vs CI/CD version mismatch causes errors
❌ Don't forget submodules: recursive - themes won't load in CI/CD
❌ Don't hardcode production URLs - use -b $CF_PAGES_URL or environment configs
❌ Don't push resources/_gen/ - generated assets, should be in .gitignore
❌ Don't use future dates carelessly - posts won't publish until date passes
❌ Don't skip .hugo_build.lock - add to .gitignore
❌ Don't mix YAML and TOML - stick to one format throughout project
Known Issues Prevention
This skill prevents 9 documented issues:
Issue #1: Version Mismatch (Hugo vs Hugo Extended)
Error: Error: SCSS support not enabled
Source: https://gohugo.io/troubleshooting/faq/#i-get-this-feature-is-not-available-in-your-current-hugo-version
Why It Happens: Theme requires SCSS/Sass processing, but Hugo Standard doesn't include it
Prevention: Always install Hugo Extended edition. Verify with hugo version | grep extended
Issue #2: baseURL Configuration Errors
Error: Broken CSS/JS/image links, 404s on all assets
Source: Hugo docs, Cloudflare Pages guide
Why It Happens: baseURL in config doesn't match deployment URL
Prevention:
- Use environment-specific configs (
config/production/hugo.yaml) - Or use build flag:
hugo -b $CF_PAGES_URL - Or set correct baseURL in hugo.yaml before build
Issue #3: TOML vs YAML Configuration Confusion
Error: Sveltia CMS fails to parse frontmatter, config not loading
Source: Sveltia CMS documentation, community reports
Why It Happens: Mixing TOML and YAML, or using TOML with Sveltia CMS (which has bugs)
Prevention: Standardize on YAML format. Create sites with --format yaml flag
Issue #4: Hugo Version Mismatch (Local vs Deployment)
Error: Features work locally but fail in CI/CD, or vice versa Source: GitHub Actions hugo-setup, Cloudflare Pages docs Why It Happens: Different Hugo versions have different features/bugs Prevention:
- Pin Hugo version in
hugo.yamlmetadata or README - Set
HUGO_VERSIONin Cloudflare Pages - Use
hugo-version: '0.152.2'in GitHub Actions
Issue #5: Content Frontmatter Format Errors
Error: Content files don't render, build fails with parse errors
Source: Hugo content management documentation
Why It Happens: Wrong delimiters (--- vs +++), invalid YAML/TOML syntax
Prevention:
- YAML: use
---delimiters - TOML: use
+++delimiters - Validate frontmatter with Sveltia CMS or YAML linter
Issue #6: Theme Not Found Errors
Error: Error: module "PaperMod" not found, blank site
Source: Hugo themes documentation
Why It Happens: Theme not installed, or theme not set in config, or Git submodules not initialized
Prevention:
- Set
theme: "PaperMod"in hugo.yaml - Use
git submodule addfor theme installation - Always
git submodule update --init --recursiveafter clone
Issue #7: Date Time Warp Issues
Error: Content missing on deployed site but visible locally
Source: Hugo date handling documentation
Why It Happens: Future-dated posts published locally (with --buildFuture) but not in production
Prevention:
- Use current or past dates in frontmatter
- Or add
--buildFutureflag to production build - Check
datefield in frontmatter
Issue #8: Public Folder Conflicts
Error: Stale content on site, Git conflicts in public/
Source: Hugo project structure best practices
Why It Happens: Committing public/ directory when it should be build output only
Prevention:
- Add
public/to.gitignore - Rebuild on every deployment
- Never commit generated files
Issue #9: Module Cache Issues
Error: failed to extract shortcode, corrupted module cache
Source: Hugo modules documentation, GitHub issues
Why It Happens: Corrupted Hugo Modules cache (when using modules instead of submodules)
Prevention:
- Run
hugo mod cleanto clear cache - Run
hugo mod tidyperiodically - Or use Git submodules instead of modules (more reliable)
Configuration Files Reference
hugo.yaml (Full Production Example)
baseURL: "https://example.com/"
title: "My Hugo Blog"
theme: "PaperMod"
languageCode: "en-us"
defaultContentLanguage: "en"
enableRobotsTXT: true
buildDrafts: false
buildFuture: false
buildExpired: false
enableEmoji: true
pygmentsUseClasses: true
summaryLength: 30
minify:
disableXML: true
minifyOutput: true
params:
env: production
title: "My Hugo Blog"
description: "A blog built with Hugo and PaperMod"
keywords: [Blog, Hugo, Tech]
author: "Your Name"
images: ["/images/og-image.jpg"]
DateFormat: "January 2, 2006"
defaultTheme: auto # dark, light, auto
disableThemeToggle: false
ShowReadingTime: true
ShowShareButtons: true
ShowPostNavLinks: true
ShowBreadCrumbs: true
ShowCodeCopyButtons: true
ShowWordCount: true
ShowRssButtonInSectionTermList: true
UseHugoToc: true
disableSpecial1stPost: false
disableScrollToTop: false
comments: false
hidemeta: false
hideSummary: false
showtoc: true
tocopen: false
assets:
disableHLJS: true
disableFingerprinting: false
label:
text: "My Hugo Blog"
icon: /favicon.ico
iconHeight: 35
homeInfoParams:
Title: "Hi there 👋"
Content: Welcome to my blog.
socialIcons:
- name: twitter
url: "https://twitter.com/"
- name: github
url: "https://github.com/"
- name: linkedin
url: "https://linkedin.com/"
- name: rss
url: "/index.xml"
cover:
hidden: false
hiddenInList: false
hiddenInSingle: false
editPost:
URL: "https://github.com/username/repo/tree/main/content"
Text: "Suggest Changes"
appendFilePath: true
fuseOpts:
isCaseSensitive: false
shouldSort: true
location: 0
distance: 1000
threshold: 0.4
minMatchCharLength: 0
keys: ["title", "permalink", "summary", "content"]
menu:
main:
- identifier: search
name: Search
url: /search/
weight: 10
- identifier: posts
name: Posts
url: /posts/
weight: 20
- identifier: archives
name: Archives
url: /archives/
weight: 30
- identifier: tags
name: Tags
url: /tags/
weight: 40
- identifier: about
name: About
url: /about/
weight: 50
outputs:
home:
- HTML
- RSS
- JSON # Required for search functionality
Why these settings:
buildDrafts: false- prevents drafts in productionenableRobotsTXT: true- SEO best practiceminifyOutput: true- smaller file sizesdefaultTheme: auto- respects user's system preferenceJSONoutput - enables client-side search- Social icons - improves discoverability
wrangler.jsonc (Cloudflare Workers)
{
"name": "my-hugo-site",
"compatibility_date": "2025-01-29",
"assets": {
"directory": "./public",
"html_handling": "auto-trailing-slash",
"not_found_handling": "404-page"
}
}
Why these settings:
directory: "./public"- Hugo's build outputhtml_handling: "auto-trailing-slash"- matches Hugo's URL structurenot_found_handling: "404-page"- serves Hugo's custom 404.html
.gitignore (Essential)
# Hugo
/public/
/resources/_gen/
.hugo_build.lock
# OS
.DS_Store
Thumbs.db
# Editor
.vscode/
.idea/
*.swp
*.swo
# Dependencies (if using npm for tools)
node_modules/
package-lock.json
# Logs
*.log
Sveltia CMS Integration (Recommended)
Why Sveltia CMS for Hugo?
✅ Hugo is Sveltia's primary use case - designed specifically for Hugo ✅ Simple setup - 2 static files, no build step required ✅ No npm dependencies - single CDN script ✅ Local backend - test CMS locally without Git ✅ YAML frontmatter - fully compatible ✅ No security vulnerabilities - lightweight, maintained ✅ Active development - focused on static site generators
Setup (5 Minutes)
1. Create admin interface - static/admin/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Content Manager</title>
</head>
<body>
<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js" type="module"></script>
</body>
</html>
2. Create CMS config - static/admin/config.yml:
backend:
name: git-gateway
branch: main
local_backend: true # Enable local testing
media_folder: "static/images/uploads"
public_folder: "/images/uploads"
collections:
- name: "blog"
label: "Blog Posts"
folder: "content/posts"
create: true
slug: "{{slug}}"
fields:
- {label: "Title", name: "title", widget: "string"}
- {label: "Description", name: "description", widget: "string", required: false}
- {label: "Date", name: "date", widget: "datetime"}
- {label: "Draft", name: "draft", widget: "boolean", default: false}
- {label: "Tags", name: "tags", widget: "list", required: false}
- {label: "Categories", name: "categories", widget: "list", required: false}
- {label: "Cover Image", name: "cover", widget: "object", required: false, fields: [
{label: "Image", name: "image", widget: "image", required: false},
{label: "Alt Text", name: "alt", widget: "string", required: false}
]}
- {label: "Body", name: "body", widget: "markdown"}
- name: "pages"
label: "Pages"
folder: "content"
create: true
slug: "{{slug}}"
filter: {field: "type", value: "page"}
fields:
- {label: "Title", name: "title", widget: "string"}
- {label: "Date", name: "date", widget: "datetime"}
- {label: "Type", name: "type", widget: "hidden", default: "page"}
- {label: "Draft", name: "draft", widget: "boolean", default: false}
- {label: "Body", name: "body", widget: "markdown"}
3. Rebuild site:
hugo
# Admin interface now at: http://localhost:1313/admin
4. Production OAuth (for Git backend):
Sveltia CMS needs OAuth for GitHub/GitLab authentication in production. Use Cloudflare Workers for OAuth proxy:
See bundled reference: references/sveltia-integration-guide.md
Key Points:
- Admin accessible at
/adminafter build local_backend: trueallows local testing without Git- YAML frontmatter format required
- Collections map to Hugo content directories
- Media files saved to
static/images/uploads
TinaCMS Integration (Not Recommended)
⚠️ Use Sveltia CMS instead. TinaCMS has significant limitations for Hugo:
Why Not TinaCMS?
❌ React-only visual editing - Hugo is Go-templated, visual editing won't work ❌ Complex setup - requires Node.js server or Tina Cloud ❌ 692 npm packages - vs Sveltia's 1 CDN script ❌ 7 security vulnerabilities - (4 high, 3 critical as of 2025-11-04) ❌ React/Next.js focused - Hugo is secondary use case ❌ YAML only - same limitation as Sveltia, without benefits
If You Must Use TinaCMS
Only consider TinaCMS if:
- Already using Tina Cloud
- Have React expertise available
- Need Tina-specific features
See bundled reference: references/tinacms-integration-guide.md (warning: not recommended)
Tailwind CSS v4 Integration
Hugo supports Tailwind CSS v4 through Hugo Pipes and the Tailwind CLI. This approach is fundamentally different from Vite-based React projects.
When to Use Tailwind vs Themes
Use Tailwind with Hugo when:
- Building custom designs without relying on themes
- Need utility-first CSS workflow
- Want complete styling control
- Prefer Tailwind over SCSS/Sass
Use themes (PaperMod, Book, etc.) when:
- Want proven, production-ready designs
- Need fast setup without custom CSS
- Happy with theme customization options
- Don't need pixel-perfect custom design
Key Differences from Vite + React
CRITICAL: Do NOT try to use the tailwind-v4-shadcn skill patterns with Hugo. That skill is for Vite + React projects and is incompatible with Hugo's asset pipeline.
| Aspect | Vite + React | Hugo |
|---|---|---|
| Build System | JavaScript (Node.js) | Go (Hugo binary) |
| Tailwind Integration | @tailwindcss/vite plugin |
Tailwind CLI + PostCSS |
| Config File | vite.config.ts |
hugo.yaml |
| Content Scanning | content: [] globs |
hugo_stats.json |
| Dev Server | Vite (port 5173) | Hugo (port 1313) |
| Dark Mode | React ThemeProvider | CSS classes or Alpine.js |
Quick Start (10 Minutes)
- Install Dependencies
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
- Configure Hugo (
hugo.yaml)
build:
writeStats: true # Generates hugo_stats.json for Tailwind
module:
mounts:
- source: assets
target: assets
- source: hugo_stats.json
target: assets/watching/hugo_stats.json
- Configure Tailwind (
tailwind.config.js)
module.exports = {
content: [
'./hugo_stats.json',
'./layouts/**/*.html',
'./content/**/*.{html,md}',
],
darkMode: 'class',
theme: {
extend: {
colors: {
primary: '#0066cc',
},
},
},
plugins: [],
}
- Configure PostCSS (
postcss.config.js)
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
- Create CSS Entry File (
assets/css/main.css)
@import "tailwindcss";
@layer base {
body {
@apply bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100;
}
}
- Process CSS in Template (
layouts/_default/baseof.html)
<head>
{{ $style := resources.Get "css/main.css" | resources.PostCSS }}
{{ if hugo.IsProduction }}
{{ $style = $style | minify | fingerprint }}
{{ end }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
</head>
- Start Development
hugo server
Complete Integration Guide
For full Tailwind v4 + Hugo setup including:
- Dark mode implementation (CSS-only and Alpine.js)
- Typography plugin setup
- Forms plugin setup
- Template integration patterns
- Common issues and solutions
- Production build optimization
See bundled resources:
- Reference Guide:
references/tailwind-v4-integration.md(comprehensive documentation) - Minimal Template:
templates/hugo-tailwind-minimal/(starting point) - Blog Template:
templates/hugo-tailwind-blog/(complete blog with Tailwind)
Tailwind-Specific Issues
Common issues when using Tailwind with Hugo (all documented with solutions in reference guide):
| Issue | Cause | Solution |
|---|---|---|
| CSS not processing | PostCSS not configured | Verify resources.PostCSS in template |
| Classes not purging | hugo_stats.json not generated |
Enable writeStats: true in hugo.yaml |
| Dark mode broken | Wrong config | Use darkMode: 'class' in tailwind.config.js |
| Asset fingerprinting fails | Incorrect Hugo Pipes usage | Use RelPermalink not Permalink |
| Hugo template syntax in CSS | Can't use {{ }} in CSS |
Apply classes in templates, not CSS |
| Version mismatch | CLI vs PostCSS plugin | Update all to same version |
Common Patterns
Pattern 1: Blog with PaperMod Theme
# Scaffold
hugo new site my-blog --format yaml
cd my-blog
git init
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
# Configure (see hugo.yaml example above)
# Create posts
hugo new content posts/first-post.md
# Develop
hugo server
# Build
hugo --minify
When to use: Personal blogs, company blogs, news sites
Pattern 2: Documentation Site with Hugo Book
# Scaffold
hugo new site docs --format yaml
cd docs
git init
git submodule add https://github.com/alex-shpak/hugo-book.git themes/hugo-book
# Configure for docs (nested navigation, search)
# See: bundled template `templates/hugo-docs/`
# Create docs
hugo new content docs/getting-started/installation.md
# Build
hugo --minify
When to use: Technical documentation, knowledge bases, API docs
Pattern 3: Landing Page
# Scaffold
hugo new site landing --format yaml
# Use custom layouts (no theme)
# See: bundled template `templates/hugo-landing/`
# Single-page structure
hugo new content _index.md
# Build
hugo --minify
When to use: Marketing sites, product pages, portfolios
Pattern 4: Multilingual Site
# hugo.yaml
defaultContentLanguage: "en"
languages:
en:
languageName: "English"
weight: 1
es:
languageName: "Español"
weight: 2
# Content structure:
# content/
# ├── posts/
# │ └── post-1.en.md
# │ └── post-1.es.md
When to use: International sites, localized content
Using Bundled Resources
Scripts (scripts/)
init-hugo.sh - Automated Hugo project setup
./scripts/init-hugo.sh blog my-blog
# Creates Hugo site with specified template (blog/docs/landing/minimal)
# Arguments: [template-type] [project-name]
deploy-workers.sh - Manual Cloudflare Workers deployment
./scripts/deploy-workers.sh
# Runs: hugo --minify && wrangler deploy
check-versions.sh - Verify Hugo and tool versions
./scripts/check-versions.sh
# Checks: Hugo version, Extended edition, wrangler, Node.js
Templates (templates/)
Complete, working Hugo projects ready to copy:
templates/hugo-blog/ - Blog with PaperMod theme
- Dark/light mode, search, tags, archives
- Sveltia CMS pre-configured
- wrangler.jsonc for Workers
- GitHub Actions workflow
templates/hugo-docs/ - Documentation site
- Nested navigation, search, breadcrumbs
- Hugo Book theme
- Sveltia CMS for docs editing
templates/hugo-landing/ - Landing page
- Hero, features, testimonials, CTA
- Custom layouts (no theme)
- Optimized for conversions
templates/minimal-starter/ - Bare-bones project
- No theme, clean slate
- Setup guide for adding themes
- Minimal configuration
When to use templates: Copy entire template directory to start a new project instantly.
References (references/)
Detailed guides that Claude can load when needed:
references/sveltia-integration-guide.md- Complete Sveltia CMS setup, OAuth configurationreferences/workers-deployment-guide.md- Cloudflare Workers deployment, CI/CD, custom domainsreferences/common-errors.md- All 9 errors with detailed solutionsreferences/theme-customization-guide.md- Overriding layouts, custom CSS, partialsreferences/hugo-vs-alternatives.md- Comparison with Next.js, Astro, Jekyll
When Claude should load these: User asks about specific topics (CMS setup, deployment, errors, theming, alternatives)
Assets (assets/)
assets/screenshots/- Visual examples of Hugo blog, Sveltia CMS, deploymentassets/diagrams/- Hugo directory structure, deployment workflow diagrams
Advanced Topics
Custom Shortcodes
Create reusable content components:
<!-- layouts/shortcodes/youtube.html -->
<div class="youtube-embed">
<iframe
src="https://www.youtube.com/embed/{{ .Get 0 }}"
allowfullscreen>
</iframe>
</div>
Usage in content:
{{< youtube dQw4w9WgXcQ >}}
Image Processing
Hugo has built-in image processing:
{{ $image := resources.Get "images/photo.jpg" }}
{{ $resized := $image.Resize "800x" }}
<img src="{{ $resized.RelPermalink }}" alt="Photo">
Taxonomy Customization
Create custom taxonomies beyond tags/categories:
# hugo.yaml
taxonomies:
tag: tags
category: categories
series: series # Custom taxonomy
Data Files
Use JSON/YAML/TOML data files:
# data/team.yaml
- name: Alice
role: Developer
- name: Bob
role: Designer
Access in templates:
{{ range .Site.Data.team }}
<div>{{ .name }} - {{ .role }}</div>
{{ end }}
Dependencies
Required:
- Hugo v0.149.0+ (Extended edition) - Static site generator
Optional (for deployment):
- wrangler v4.0.0+ - Cloudflare Workers deployment
- Git v2.0+ - Version control and theme submodules
Optional (for CMS):
- Sveltia CMS (latest) - Content management (CDN-based, no installation)
Official Documentation
- Hugo: https://gohugo.io/documentation/
- PaperMod Theme: https://github.com/adityatelange/hugo-PaperMod/wiki
- Sveltia CMS: https://github.com/sveltia/sveltia-cms
- Cloudflare Workers: https://developers.cloudflare.com/workers/
- Hugo Themes: https://themes.gohugo.io/
Package Versions (Verified 2025-11-04)
Hugo: v0.152.2+extended (October 24, 2025) PaperMod: Latest (via Git submodule) Sveltia CMS: Latest (via CDN) Wrangler: v4.37.1+ (v4.45.3 available)
Production Example
This skill is based on live testing:
- Test Site: https://hugo-blog-test.webfonts.workers.dev
- Build Time: 24ms (20 pages)
- Deployment Time: ~21 seconds
- Errors: 0 (all 9 known issues prevented)
- Validation: ✅ Hugo + PaperMod + Sveltia + Workers deployed successfully
Troubleshooting
Problem: "SCSS support not enabled" error
Solution: Install Hugo Extended, not Standard. Verify with hugo version | grep extended
Problem: Blank site after deployment
Solution:
- Check
themeis set in hugo.yaml - Verify theme exists in
themes/directory - Run
git submodule update --init --recursive
Problem: Assets (CSS/JS/images) not loading
Solution:
- Check
baseURLin hugo.yaml matches deployment URL - Or use
hugo -b https://your-site.com - Or use environment-specific config
Problem: Posts not appearing on site
Solution:
- Check
draft: falsein frontmatter - Check date is not in future
- Or build with
--buildDraftsand--buildFutureflags
Problem: Theme not found in CI/CD
Solution: Add submodules: recursive to checkout action in GitHub Actions
Problem: Sveltia CMS not loading
Solution:
- Rebuild site with
hugo - Check
/admindirectory exists inpublic/ - Verify
config.ymlsyntax - Check browser console for errors
Complete Setup Checklist
Use this checklist to verify your setup:
- Hugo Extended v0.149.0+ installed (
hugo versionshows "+extended") - Project created with
--format yaml(hugo.yaml exists) - Theme installed and configured (via Git submodule or Hugo Module)
-
baseURLconfigured correctly in hugo.yaml -
.gitignoreincludespublic/andresources/_gen/ - Sample content created and renders correctly
- Dev server runs without errors (
hugo server) - Production build succeeds (
hugo --minify) - wrangler.jsonc configured for Workers (if deploying)
- Sveltia CMS configured (if using CMS)
- GitHub Actions workflow configured (if using CI/CD)
- Deployed successfully (if deploying to Workers)
Questions? Issues?
- Check
references/common-errors.mdfor all 9 documented errors and solutions - Verify all steps in the setup process
- Check official docs: https://gohugo.io/documentation/
- Ensure Hugo Extended is installed (most common issue)
This skill provides production-ready Hugo setup with zero errors. All 9 common issues are documented and prevented.