Configuration
Every Writedocs site is described by a single writedocs.json file at the root of the content directory. This page documents every field it accepts.
The whole file is validated against a schema (src/lib/config.ts in the Writedocs package) on every dev and build run. Invalid config fails immediately with a readable error instead of producing a broken site.
Top-level fields
| Field | Type | Required | Default |
|---|---|---|---|
name | string | yes | — |
description | string | no | — |
styles | object | no | { colors: { primary: "#6366f1" } } |
navigation | array | yes | — |
topbar | object | no | { links: [] } |
footer | object | no | { columns: [] } |
socials | object | no | {} |
name
The site name. Shown in the browser tab title (Page Title · {name}) and in the topbar next to the logo.
{ "name": "My Docs" }description
Used as the default <meta name="description"> for pages that don’t set their own description in frontmatter.
styles
Controls colors and branding.
styles.colors
| Field | Type | Default |
|---|---|---|
primary | string (any valid CSS color) | #6366f1 |
background | string | #ffffff |
text | string | #0f172a |
{
"styles": {
"colors": {
"primary": "#16a34a",
"background": "#ffffff",
"text": "#0f172a"
}
}
}styles.logo and styles.favicon
Both accept a path to an image, resolved relative to the site root.
{
"styles": {
"logo": "/logo.svg",
"favicon": "/favicon.svg"
}
}navigation
An array describing the sidebar. Each entry is either:
- A page slug — a string matching a file under
docs/by path, without its extension."guides/components"matchesdocs/guides/components.mdx. - A group — an object with
group(the heading shown above its pages) andpages(an array that can itself contain slugs or further nested groups).
{
"navigation": [
{ "group": "Getting Started", "pages": ["index", "getting-started"] },
{
"group": "Guides",
"pages": ["guides/components", "guides/configuration"]
}
]
}The order pages appear in navigation is also the order used for the automatic previous/next links at the bottom of each page — reorder navigation to reorder those links too.
topbar
topbar.links
An array of { label, href } objects, rendered top-right on every page.
{
"topbar": {
"links": [
{ "label": "GitHub", "href": "https://github.com/your-org/your-repo" },
{ "label": "Support", "href": "mailto:support@example.com" }
]
}
}footer
footer.columns
An array of columns rendered below the page content, each with an optional title and a list of { label, href } links (same shape as topbar.links above).
{
"footer": {
"columns": [
{
"title": "Resources",
"links": [
{ "label": "Documentation", "href": "/docs/getting-started/" },
{ "label": "Blog", "href": "https://example.com/blog" }
]
}
]
}
}socials
A free-form map of platform name to URL, rendered as a row of icon links in the footer alongside footer.columns above (or on its own, with no columns set). Each key doubles as the icon reference (see Components’s icon syntax) — a bare name resolves against the default Lucide set, or use an explicit "collection:icon-name" key when that isn’t right for a given platform.
{
"socials": {
"twitter": "https://twitter.com/example",
"github": "https://github.com/example"
}
}Page frontmatter
Separate from writedocs.json, each .mdx file has its own frontmatter:
| Field | Type | Required |
|---|---|---|
title | string | yes |
description | string | no |
---
title: Getting Started
description: Optional, used for the page's <meta name="description">
---title is rendered as the page’s <h1> automatically — don’t also write it as a # Heading in the body, or it’ll appear twice.