Frontmatter
A page starts with frontmatter: YAML between two --- lines, describing the page.
---
title: Webhooks
description: Get an HTTP request when something changes in your account.
sidebarTitle: Webhooks
icon: webhook
tag: New
---
Webhooks send ...| Field | Type | What it does |
|---|---|---|
title | string | The page’s heading and name |
description | string | A summary, for search engines and AI tools |
slug | string | A different address |
mode | string | The page’s layout |
draft | boolean | Keep the page off the published site |
sidebarTitle | string | A shorter name in the sidebar |
icon | string | An icon in the sidebar |
tag | string | A label in the sidebar |
deprecated | boolean | A Deprecated label |
hidden | boolean | Leave the page out of the sidebar |
url | string | Make the page a link to another site |
hideFooterPagination | boolean | No previous and next links |
openapi | string | An API endpoint for the page |
hideApiMarker | boolean | No method label in the sidebar |
seo | object | Meta tags for search engines and social media |
Every field is optional. A page in the navigation doesn’t need frontmatter at all; one outside it needs at least the --- lines to be a page - see Project structure.
The page
title
The page’s main heading, its name in the sidebar and in previous/next links, and the browser tab’s title. Without it, the title comes from the file name: getting-started.mdx is “Getting started”, and an index.mdx takes its folder’s name.
Don’t repeat the title as a # heading in the page - it’s already shown.
description
A one-sentence summary of the page. It’s the page’s <meta name="description"> - what search engines show under the link, and the text of link previews. It’s also the page’s summary in llms.txt, and in the MCP server’s page list. Without it, the page uses the site’s description from writedocs.json.
slug
A different address for the page, without moving the file:
---
title: Authentication
slug: guides/auth
---docs/security/authentication.mdx with this slug is served at /guides/auth/. The navigation still lists it by its file: docs/security/authentication. Slashes at either end don’t matter - guides/auth and /guides/auth/ are the same - and slug: / makes the page the home page.
When you change a published page’s address, add a redirect from the old one.
mode
The page’s layout - how much of the site’s frame (topbar, sidebar, table of contents) is around it: default, wide, frame, custom or blank. See Page modes.
draft
draft: true keeps the page off the published site while you write it:
---
title: Webhooks
draft: true
---The published site doesn’t have the page at all: it has no address, and it isn’t in the navigation, the site’s search, sitemap.xml, llms.txt, llms-full.txt or the MCP server, or anyone’s previous/next links. Take draft: true out (or set draft: false) and the page is published as usual.
writedocs dev shows drafts, so you can see how they look: at the top of the page a Draft: not published strip, and a Draft label next to its name in the sidebar. Turning draft on or off while writedocs dev runs updates the page without a restart.
What else changes while a page is a draft:
- The navigation. Its entry in
writedocs.json’s navigation is left out, and so is a group or tab whose pages are all drafts - you don’t have to edit the navigation. A group whose ownpageis a draft keeps its other pages. - Links to it lead nowhere on the published site.
writedocs broken-linkslists them, saying the page is a draft. - A redirect to it stays, and shows “not found” until the page is published.
- A draft home page (
index.mdx): the site’s address opens the navigation’s first page instead, as on a site with no home page. - Its folder’s address. When a folder’s own page (
guides/index.mdx) is a draft,/guides/opens the folder’s first page instead, as for any folder with no page of its own.
The build lists each of these - every navigation entry, group and tab it left out, every redirect to a draft and a draft home page - as warnings, and says how many drafts it left out.
draft has to be true or false: draft: yes and draft: "true" are errors in writedocs validate. writedocs validate checks drafts like any other page, so they’re ready when you publish them. Only pages have frontmatter: snippets and other files can’t be drafts, and neither can the API pages generated from an OpenAPI spec.
draft or hidden
| Hidden page | Draft | |
|---|---|---|
| Published at its address | Yes | No |
| In the sidebar and previous/next links | No | No |
| In the site’s search | Yes | No |
In search engines, sitemap.xml, llms.txt, the MCP server | No | No |
| Links to it | Work | Broken |
In writedocs dev | Like on the site | Shown, marked as a draft |
Use hidden for a page that’s finished but shouldn’t be in the menus - one you link to from somewhere else. Use draft for a page that isn’t ready. With both, draft wins.
How the page appears in the sidebar
sidebarTitle
A shorter name for the sidebar and menus, when the title is long:
---
title: Authenticating requests with OAuth 2.0
sidebarTitle: OAuth 2.0
---The page’s heading and previous/next links still use title.
icon
An icon before the page’s name in the sidebar: an icon name, an emoji, or an image - see Icons.
tag
A small label after the page’s name in the sidebar, like New or Beta.
deprecated
deprecated: true shows a Deprecated label next to the page’s title, and in the sidebar.
hidden
hidden: true leaves the page out of the sidebar, menus and previous/next links, even when the navigation lists it. The page is still published at its address, and links to it work.
A hidden page is also noindex - out of search engines, sitemap.xml and llms.txt - unless it sets seo.noindex: false. To hide a whole tab, version or product, see Hidden sections.
url
Makes the page a link to another site:
---
title: Status page
url: https://status.example.com
---Its sidebar entry opens url in a new tab, and its own address redirects there. The page’s content isn’t shown anywhere, and the page is left out of sitemap.xml, llms.txt and previous/next links.
hideFooterPagination
hideFooterPagination: true removes the Previous and Next links at the bottom of the page.
API pages
openapi
Makes the page an API reference page for one endpoint: your text, then the endpoint’s parameters, responses and Try it playground, from the spec.
---
title: Create a refund
openapi: POST /refunds
---See Your own page for an endpoint.
hideApiMarker
On an API page, hideApiMarker: true removes the method label (GET, POST, …) from its sidebar entry.
seo
Meta tags for this page. Each field replaces the site’s default from writedocs.json’s seo; the rest still apply.
---
title: Enterprise SSO
seo:
ogImage: /images/social/sso.png
ogType: article
twitterCard: summary_large_image
keywords:
- sso
- saml
noindex: false
title: "Single sign-on (SSO) with SAML - Acme"
description: Connect Acme to Okta, Entra ID or any SAML identity provider.
canonical: /docs/security/sso/
metatags:
"og:locale": en_GB
---The page’s <title> - what the browser tab and search results show - and the title in link previews. Used exactly as written; the site’s name isn’t added. The heading on the page and the sidebar keep the page’s title.
The description search engines and link previews get, when it should differ from the page’s description.
The page’s canonical URL, when it isn’t its own address: a path on the site, or a full URL. See Canonical URLs.
The image in link previews: a path in your project, or a URL. Without it, the site’s seo.ogImage - or a picture generated for the page.
The page’s og:type.
The kind of preview on X (Twitter).
The page’s <meta name="keywords">.
true keeps the page out of search engines, sitemap.xml, llms.txt, llms-full.txt and the MCP server. The page is still published and in the site’s search.
The whole <meta name="robots"> value, like "noindex, follow". Replaces noindex. See Leaving pages out of search engines.
Other meta tags for this page, as name and content. They’re added to the site’s; one with the same name replaces it. See Other meta tags.
Structured data of your own for this page - a schema.org block, or a list of them. See Structured data.
Mistakes
A field with the wrong type, or a mode that doesn’t exist, is an error in writedocs validate, with the file and line. Frontmatter that isn’t valid YAML is too - a common cause is a value with a colon in it, which needs quotes: title: "Step 2: Configure".