Teams with multiple products often face a choice: run N separate docs sites (one subdomain per product, painful to maintain, no shared chrome), or cram everything into a single navigation tree (confusing for readers who care about only one product).
NookDocs gives you a third option: one site, N product switchers. A dropdown next to the logo lets readers pick their product; the sidebar, URL prefix, and (future) chrome overrides update accordingly.
Declare products
In Configurations → Products (or direct nookdocs.config.json):
{
"products": [
{ "product": "Cloud", "default": true, "description": "Managed hosting" },
{ "product": "Enterprise", "description": "Self-hosted", "tag": "Beta", "status": "beta" }
]
}productstringrequiredProduct name. Used as both the switcher label and the default URL slug.
descriptionstringOne-line description shown below the product name in the switcher dropdown. Helps readers pick the right one.
defaultbooleanThe product loaded when a reader lands on / without a product prefix. At most one default.
slugstringURL prefix override. Defaults to the slugified product name (e.g. "Cloud Connect" → cloud-connect).
Repo layout
your-repo/ # the docs base
├── nookdocs.config.json
├── introduction.mdx ← Cloud (default), no prefix
├── quickstart.mdx
├── api/
│ └── overview.mdx
└── enterprise/ ← Enterprise, URL prefix /enterprise
├── introduction.mdx
├── installation.mdx
└── admin/
└── sso.mdxReaders land on / → see Cloud docs. They pick "Enterprise" from the switcher → URL becomes /enterprise/ → Enterprise tree loads. Same pattern for every product.
When to use products vs versions vs tabs
Products
Different audiences. Each product has its own concepts, onboarding, and audience. Cloud users and Enterprise users rarely read the same pages.
Versions
Same product, multiple generations. v1 / v2 / v3 readers are mostly the same people who happen to be locked onto different releases.
Tabs
Same product, different tasks. Guides / API Reference / Changelog — everyone reads all tabs, they just organize information.
Combining them:
Products × versions: Cloud v1 / v2 / v3 AND Enterprise v1 / v2. Nest
versions[]inside eachproduct. Per-product versions ship as part of the Phase 3+ follow-up (see Navigation schema).Products × languages: Cloud in en / tr AND Enterprise in en / tr. Nest
languages[]inside each product (planned).
Shared vs product-specific chrome
Elements that look the same across products (logo, brand colors, theme) are defined at the top level of the config and apply everywhere. Product-specific chrome lives on the product entry:
{
"products": [
{
"product": "Cloud",
"default": true,
"navbar": {
"links": [{ "label": "Pricing", "href": "https://example.com/cloud/pricing" }]
},
"colors": {
"primary": "#3b82f6"
}
},
{
"product": "Enterprise",
"navbar": {
"links": [{ "label": "Contact sales", "href": "mailto:sales@example.com" }]
},
"colors": {
"primary": "#8b5cf6"
}
}
]
}Per-product navbar / colors / footer / banner are in the schema today but the renderer uses the top-level config for every product. Per-product chrome wiring ships in a follow-up sprint.
Shared chrome: global
When something must appear on every product (status page anchor, global changelog, corporate privacy link), use the top-level global config instead of duplicating it:
{
"global": {
"anchors": [
{ "anchor": "Status", "icon": "activity", "href": "https://status.example.com" }
],
"dropdowns": [
{
"dropdown": "Changelog",
"icon": "history",
"pages": ["docs/changelog/2026-q1"]
}
]
}
}global.anchors + global.dropdowns render at the top of every sidebar, regardless of active product. The Configurations → Global nav section lets you edit anchors from the dashboard; dropdowns require direct nookdocs.config.json edit.
Onboarding a reader to the right product
Link pages across products using absolute paths:
For self-hosted docs, see [Enterprise → Installation](/enterprise/installation).When a reader lands from an ad or blog post, they'll arrive on a specific product's page; the switcher shows them which one. This is usually enough context — but for marketing landing pages you may want to add a Banner that surfaces the product switcher:
<Banner variant="info">
Reading Cloud docs. Looking for self-hosted? [Switch to Enterprise](/enterprise/).
</Banner>Migration: single-product → multi-product
Wrap existing content into a default product
Your existing docs/ stays where it is. Add a default product entry: { "product": "Your Product", "default": true }. Nothing changes visually because the default product has no URL prefix.
Add the second product's folder
docs/enterprise/ (or whatever slug you pick). Drop at least an introduction.mdx so the switcher has somewhere to route.
Add the second product entry
{ "product": "Enterprise", "description": "Self-hosted" } in products[]. Save config, wait for sync, the switcher appears in the navbar.
Cross-link where useful
Banners on product-specific pages that point readers to the other product when relevant. "This feature is Cloud-only. For Enterprise, see Self-hosted SSO."
No existing URLs break — the default product's content still serves at /. Non-default product URLs gain the prefix and start resolving only after you add the folder + config entry.
Search and AI Assistant
Search (Postgres FTS) indexes every page regardless of product. A Cloud reader searching "SSO" will see both Cloud SSO and Enterprise SSO results. Per-product search scoping ships when the full routing layer lands.
The AI Assistant has the same caveat — it retrieves from the full docs tree. For clean-separation customers, disable the widget on one product and leave it on the other via ai.assistant.enabled per scope (planned).