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 env