site.json
Complete reference for every site.json key, the theme's configuration file.
site.json lives in your site root, next to hugo.toml. It is validated at build time: a missing file or an empty themes list fails the build with a clear message. Everything else is optional with sensible defaults.
Note
The dev server does not watch
site.json. Restarthugo serverafter changes.
This site’s own site.json uses every key below.
Required
{
"title": "My Product Docs",
"themes": [
{ "id": "light", "label": "Light", "dark": false, "default": true },
{ "id": "dark", "label": "Dark", "dark": true, "default": true }
]
}| key | meaning |
|---|---|
title |
site name used as the topbar fallback logo, <title>, and social cards |
themes |
available color themes. Each id maps to static/docs/css/theme-<id>.css. default: true marks the eager-loaded default of each family (light/dark). See Themes |
Branding & navigation
| key | example | meaning |
|---|---|---|
logo |
"/docs/media/svg/logo.svg" |
topbar/homepage logo. Falls back to title text if the file doesn’t exist |
favicon |
"/docs/media/svg/favicon.svg" |
favicon path |
defaultLanguage |
"en" |
UI language for pages without a path language (homepage, 404) and the x-default hreflang |
menu.links |
[{ "label": "Support", "url": "mailto:…", "external": true }, { "type": "divider" }] |
links in the settings drawer |
footer |
{ "copyright": "© :YEAR: Acme", "social": [{ "name": "GitHub", "icon": "github", "url": "…" }], "repoUrl": "…" } |
footer content. :YEAR: becomes the current year. Icons: github, linkedin |
Sub-path deployments (GitHub/GitLab Pages)
Write internal URL values (
menu.links,landing.ctas) without a leading slash, e.g."changelog/"rather than"/changelog/". Hugo resolves slash-less values against yourbaseURL, so the same site.json works at the domain root and underhttps://host/project/. The paths insideversions.jsonare navigated to verbatim, so on a sub-path deployment they must include the sub-path. The release pipeline’s generated manifest handles that automatically.
SEO & social
| key | example | meaning |
|---|---|---|
social.cover |
"/docs/media/banner.png" |
default Open Graph/Twitter banner (per-page override: cover front matter) |
themeColor |
{ "light": "#fff8f6", "dark": "#1a110f" } |
browser-UI tint per color scheme |
Page features
| key | example | meaning |
|---|---|---|
editUrl |
"https://gitlab.com/acme/docs/-/edit/main/content" |
base for “Edit this page” links (page path is appended). Omit to hide. |
feedback.url |
"https://feedback.acme.com/api" |
enables the “Was this page helpful?” widget. See Page extras for the payload and CORS requirements |
announcement |
{ "id": "rel-2", "text": "**v2 is out** - [notes](/changelog/)", "dismissible": true } |
dismissible bar above the topbar. Markdown text. A new id re-shows it to everyone |
Homepage
"landing": {
"tagline": "Versioned, multilingual product documentation.",
"ctas": [
{ "label": "Get started", "url": "/docs/v1_0_0/en/getting-started/", "primary": true },
{ "label": "Changelog", "url": "/changelog/" }
],
"features": [
{ "title": "Instant search", "text": "Client-side, no server required." }
]
}All three sub-keys are optional. Without the block the homepage renders the title, description and a “Get started” button.