Protected sections
Any tab, product, version, language or dropdown can be protected: give it access, the name of an access rule, and every page under it opens only for the readers that rule lets in - with a password, or for a list of email addresses. Use it for the parts of your docs that aren’t for everyone: a partner program, internal runbooks, a customer-only API.
{
"navigation": {
"tabs": [
{ "tab": "Guides", "pages": ["index", "guides/start"] },
{
"tab": "Partners",
"access": "partners",
"lock": true,
"pages": ["partners/intro", "partners/payouts"]
},
{ "tab": "Internal", "hidden": true, "access": "staff", "pages": ["internal/runbook"] }
]
}
}Only the WriteDocs platform protects these pages. writedocs.json names the rule; the rule itself - its password or its list of emails - is set up on the platform, never in your project. A build hosted anywhere else serves the pages to everyone, and writedocs build and writedocs validate say so every time.
The name of an access rule: 1 to 40 lowercase letters, numbers and hyphens, like partners or team-2. Every page under the item - its sidebar, however deep, its own page, and the API pages an OpenAPI group in it generates - is protected by that rule. The name isn’t a secret: anyone can read it in writedocs.json. Two items can use the same rule.
Shows a padlock next to the item’s name wherever it’s listed - the tabs, a tab’s menu, the switchers in the top bar and the sidebar, and the mobile menu - so readers know they’ll be asked to sign in. Screen readers announce it as “Requires sign-in”. Only for an item with access: writedocs validate rejects it anywhere else.
access works on the same items as hidden. It can’t go on an item with href (a link has no pages to protect) or in global.dropdowns.
Rules inside rules
When a protected item holds another protected item, the inner rule wins: its pages are protected by the inner rule only.
{
"tab": "Partners",
"access": "partners",
"products": [
{ "product": "Program", "pages": ["partners/intro"] },
{ "product": "Revenue", "access": "staff", "lock": true, "pages": ["partners/revenue"] }
]
}Here partners/intro needs the partners rule, and partners/revenue needs staff - a partner can’t open it.
What readers see
- Protected doesn’t mean hidden. A protected item stays in the tabs and menus, so readers know it’s there - add
lockto show it needs a sign-in. Opening one of its pages asks for the rule’s password or email first. - Protected and hidden. To keep the item out of every menu too, add
"hidden": true- see Hidden sections. Share its pages’ addresses with the people it’s for; they still sign in. - The site’s address (
/) never opens a protected page, and a folder address opens a public page when the folder has one. A folder with only protected pages in it asks for the sign-in.
What’s left out of public files
A protected page is never listed where anyone can read it:
- it isn’t in
sitemap.xml, and it tells search engines not to index it, whatever its ownseosays; - it isn’t in
llms.txtorllms-full.txt, and the site’s MCP server doesn’t serve it; - it gets no link-preview image;
- the site’s search never finds it;
- the old address of an API page whose endpoint has no tag (
/api/untagged/..., from before Writedocs 0.10.14) redirects to it only for readers the rule lets in.
An OpenAPI group shown as Scalar’s API reference is protected like the rest: its reference page carries your spec inside the page, never in a file of its own, so the spec is behind the rule too, and its download button is turned off.
Search
Each access rule has a search of its own. Searching from a protected page finds the pages of its rule - from every item that uses it - and never another rule’s pages or the site’s public ones. With "searchPublic": true on the protected item, its search finds the public pages too:
{ "tab": "Partners", "access": "partners", "searchPublic": true, "pages": ["partners/intro"] }A part that is protected and hidden searches only among its own pages, like any hidden section.
What isn’t protected
- Images and files. An image or a download stays public, even when only a protected page uses it - anyone with its address can open it. What’s protected is the page: its text, its Markdown copy and its search results. Keep anything sensitive out of images and downloads.
- Snippet components. A
.jsxor.tsxsnippet is built into a script file of the site’s, and that file isn’t protected - keep sensitive text in the page itself, or in an.mdxsnippet, which becomes part of the page. - The item’s name and description, in the tabs and menus, unless the item is
hidden. - A redirect in
writedocs.jsonthat leads to a protected page: the redirect itself is public, and only shows the page’s address. writedocs dev: nothing is protected in the preview on your computer - every page opens.
On your own host
access needs the WriteDocs platform: on any other host, the pages are public, like any other page. To keep docs private there, put a login in front of their addresses - on Cloudflare, with Cloudflare Access - or publish them as a separate site.