Static Websites
Each child of www/ is a self-contained site root whose content, layouts, assets, and configuration travel together and whose output is disposable.
- Kind
- Architecture
- Domain
- Product Code
- Applies at
www/- Status
- Stable
- Source · managed
www/README.md
01 Defines
The home for static and content-driven websites: one directory per site under www/, each holding everything it needs to build, and each rendered into the single shared public/ output.
02 Applies when
- A repository publishes generated static content — a Hugo site, a documentation site, a landing page.
- A site’s primary output is files that can be uploaded and served as they are.
- More than one site is published from the same repository.
03 Boundaries
- Frontend applications with client-side state, routing, or their own build pipelines belong in
app/, notwww/. - Generated output is never a source; it is rebuilt from the site root.
- Sites do not reach into each other’s layouts or themes through relative paths.
Expected behaviour
- 01Site content, layouts, assets, and configuration all live inside the site root.
- 02Generated site output is disposable and never committed.
- 03Shared layouts or assets move into an explicit shared location only once more than one site needs them.
- 04Sites are declared in
HUGO_DIRS; the first builds intopublic/and each additional site intopublic/<name>/.
Behaviour#
www/ is a logical grouping, not a site. Every child directory is a complete
site root: point a static site generator at it and it builds, with nothing
borrowed from a sibling. That keeps each site understandable on its own and lets
a site be moved, renamed, or deleted without breaking another.
The make module for Hugo turns the declared sites into one output tree. The
first site in HUGO_DIRS owns the root of public/; every later site is nested
beneath it under its own directory name.
- 01
Declare
repository.mklists the site roots inHUGO_DIRSMake Module Registries - 02
Prepare
prepare.hugostages generated content, or prints askip:Staged Content Mounts - 03
Build
hugo --minify --cleanDestinationDirper existing site root - 04
Publish
public/is the one build output; link checking and deployment both read it Static Site Delivery
A declared site whose directory does not exist is skipped rather than failing
the build, and when none exist the module says so with a skip: line.
www or app#
www/
- Hugo-style sites and documentation sites
- Landing pages and other static publishing targets
- Output that is generated once and served as files
app/
- SPAs and other app-style clients
- Rich client-side state and routing
- Build pipelines or deployment concerns beyond static publishing
Layout#
- www/
- README.md Owner documentation for the area Owner Documentation
- <site>/ One self-contained site root
- content/ Markdown with front matter
- layouts/ Templates
- assets/ Processed assets (CSS, JS)
- static/ Copied to the output verbatim
- hugo.yaml Site configuration
- public/ Disposable build output, shared by every site
- <second-site>/ Additional sites nest under their own name
Examples#
The build loop gives the first existing site the root of public/ and nests
every other one:
check.hugo: prepare.hugo ## Build Hugo sites into public/
@existing=''; for site in $(HUGO_DIRS); do [ -d "$$site" ] || continue; existing="$$existing $$site"; done; \
if [ -n "$$existing" ]; then set -e; first=1; for site in $$existing; do dest="$(REPO_ROOT)/public"; if [ $$first -eq 0 ]; then dest="$(REPO_ROOT)/public/$$(basename "$$site")"; fi; hugo --source "$$site" --destination "$$dest" --minify --cleanDestinationDir; first=0; done; else printf 'skip: no Hugo sites (directories not found)\n'; fi
Cleaning removes public/, any configured staging paths, and each site’s own
public/ and .hugo_build.lock, so a clean build always starts from the site
roots alone.
Connections