๐ Related cheat sheets:
- ๐ Core: hugo.md
- ๐งพ Markdown: hugo_markdown.md
Goal: quickly wire up themes, modules, and asset pipelines.
๐จ Using a theme quickly
Classic theme usage with a themes/ folder:
- Add a theme as a Git submodule or copy it:
git submodule add https://github.com/the/theme.git themes/the-theme- Reference it in hugo.toml:
theme = "the-theme"- Start the server and verify:
hugo server -DThis approach is simple but less flexible than Hugo Modules for sharing components.
๐งฉ Hugo Modules for themes and components
Modern Hugo prefers modules to manage themes and building blocks.
Initialize modules in your site root:
hugo mod init github.com/you/my-siteImport a theme or component module in hugo.toml:
[module]
[[module.imports]]
path = "github.com/the/theme"
# Example of stacking multiple components
[[module.imports]]
path = "github.com/you/docs-components"Useful commands:
- hugo mod get github.com/the/theme # fetch or update a module
- hugo mod tidy # clean unused module references
- hugo mod graph # inspect dependency graph
Modules work well for:
- Full themes.
- Theme components (navigation, footer, shortcodes, patterns).
- Internal shared building blocks across multiple sites.
๐งฑ Theme and layout structure recap
Typical theme layout structure inside themes/the-theme/:
themes/the-theme/
archetypes/
assets/
layouts/
_default/
partials/
shortcodes/
static/
theme.tomlUnion file system rules:
- Your project files take precedence over theme files.
- You can override any template by recreating its path in your site layouts/.
- Multiple modules can contribute layouts, partials, shortcodes, and assets.
๐งต Theme components and composition
- Theme components are smaller modules designed to be layered.
- Example composition in hugo.toml:
[module]
[[module.imports]]
path = "github.com/vendor/base-theme"
[[module.imports]]
path = "github.com/vendor/docs-component"
[[module.imports]]
path = "github.com/you/site-overrides"Patterns:
- Keep shared UI patterns in dedicated component modules.
- Use site-overrides as the final layer for project-specific tweaks.
- Prefer modules over copying theme files to stay up to date.
๐งช Minimal modules-based stack example
Conceptual layout for a modules-based stack (often separate repositories in practice):
my-hugo-stack/
site/ # main site (hugo mod init github.com/you/site)
base-theme/ # base theme module (hugo mod init github.com/you/base-theme)
docs-components/ # component module (hugo mod init github.com/you/docs-components)- site imports base-theme and docs-components via [module.imports] in its hugo.toml.
- Each folder is its own Hugo module; in reality they are usually individual Git repositories.
- This mental model helps you reason about what lives where and how overrides flow.
๐งฌ Assets, Hugo Pipes, and static files
Two main places for files:
- static/: copied verbatim to the output root.
- assets/: processed via Hugo Pipes and only emitted when referenced.
Basic CSS pipeline example in a template:
{{ $css := resources.Get "css/main.scss" | toCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}">Key Hugo Pipes capabilities:
- Minification of CSS and JS.
- Bundling multiple resources into one file.
- Fingerprint and SRI hashes for cache-busting.
- JavaScript building with esbuild.
- PostCSS processing.
Use assets/ for everything that should go through a build step, and static/ for raw files like favicons or downloaded fonts.
๐ Tailwind, PostCSS, and JS toolchains
High-level Tailwind integration sketch (site or theme root):
- Install Node dependencies:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init-
Configure Tailwind content paths to watch Hugo output templates and content.
-
Configure PostCSS (postcss.config.js) to run Tailwind and Autoprefixer.
-
Wire CSS through Hugo Pipes (example):
{{ $css := resources.Get "css/main.css" |
postCSS (dict "config" "postcss.config.js") |
minify |
fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}">- During development, run both Hugo and a Node watcher when needed.
This pattern also works for design systems like Flowbite or custom component libraries.
๐ Ecosystem and helpers
- Official themes directory: https://themes.gohugo.io
- Many themes use Tailwind CSS, Hugo Pipes, and modules under the hood.
- Starter kits such as blog or landing-page templates are good references for:
- Directory structure and layouts.
- Module configuration.
- Asset pipeline wiring.
- Community guides show concrete setups for Hugo plus Tailwind and component libraries.
When adopting a theme or starter, keep your overrides shallow and module-based so you can still pull upstream updates without heavy merges.
โ ๏ธ Gotchas
- Avoid configuring both theme = โโฆโ and [module.imports] for the same theme; pick one primary mechanism to reduce confusion.
- When a module or theme updates, remember to run hugo mod get -u ./โฆ or at least hugo mod get for the affected path.
- Files in your project layouts/ and static/ override the same paths in themes and modules; unexpected output often comes from an older override.
- With Tailwind and PostCSS, forgetting to run the Node watcher or to include the generated CSS through Hugo Pipes can make your styles appear missing.