Multi-product documentation: how to structure docs when you ship more than one product
One doc site works fine for one product. The moment you ship a second, you need a structure — or you get chaos. Here's what actually works.
The problem starts with a second product. You already have docs for your API. Then the mobile SDK ships. Then the CLI. Then the admin dashboard. Now you have four audiences with different needs, different vocabulary, and different levels of technical depth — all trying to navigate the same sidebar tree you designed when there was only one thing to explain. Nobody told a dashboard user they’d have to scroll past three SDK reference pages to find the settings guide. Nobody told an API developer that the getting-started page at the top of the nav is actually for the no-code editor.
This is the multi-product documentation problem, and most teams don’t realize they have it until users are already lost.
When one doc site stops being enough
A single doc site works well under two conditions: there is one primary audience, and the surface area is small enough that a flat nav handles it. Both conditions tend to break at the same time.
The signals that you have outgrown a single-audience structure:
- Support tickets where users describe following docs that were not meant for them (“I followed the SDK tutorial but I only use the REST API”)
- Navigation trees with more than 40 pages at the top level, forcing users to skim-scroll to find anything
- Separate teams responsible for separate products, both editing the same repository and creating merge conflicts weekly
- A search box that returns results from three products when the user was only thinking about one
The underlying issue is that a single navigation model assumes a single mental model. Once you have two products, you have two different contexts users are trying to work from. Forcing both into one flat structure doesn’t create a unified experience — it creates a confused one.
The right time to restructure is before you feel the pain, not after. If you have two products today and plan to ship a third in the next six months, the architecture decision you make now will either scale or collapse under that load.
Three structures teams try (and why two of them fail)
Monorepo docs: one tree, everything inside
The default choice, because it requires no new tooling and no new decisions. Everything lives under one navigation root, organized by product:
docs/
├── api/
│ ├── getting-started.md
│ └── reference/
├── sdk/
│ ├── getting-started.md
│ └── ios/
├── cli/
│ └── commands.md
└── dashboard/
└── overview.md
❌ What breaks: the navigation model is product-centric but the user experience is not. Users don’t arrive thinking “I need to find the sdk/ folder.” They arrive with a task: “I want to add authentication to my iOS app.” Whether that task maps to sdk/ios/auth.md or api/auth/mobile.md is not obvious — and both pages probably exist, saying slightly different things.
The monorepo structure also creates organizational debt. When the SDK team and the API team both push changes through the same docs/ repository, you have two teams with different release cadences, different audiences, and different content strategies sharing a single CI pipeline and a single deploy. The API team cannot publish a hotfix without waiting for the SDK team’s draft to clear review.
Siloed sites: a separate domain per product
The opposite reaction: when the monorepo gets too chaotic, some teams split into fully separate sites. api-docs.company.com, sdk-docs.company.com, cli-docs.company.com. Each team controls their own repository, their own navigation, their own deploy pipeline.
❌ What breaks: the user cannot move between products. A developer building an integration that touches your API and your SDK has to maintain two browser tabs, two search contexts, and two mental maps. When a concept spans products — authentication, rate limits, error codes — it gets documented twice, diverges over time, and neither version is canonical.
More practically: siloed sites multiply the maintenance surface. Every shared piece of content — company-wide rate limits, shared authentication flows, billing documentation — now has to be either duplicated across all sites or linked externally, which means it will eventually drift.
Teams that go silo often cite “team autonomy” as the reason. But team autonomy at the cost of user coherence is the wrong tradeoff.
Federated docs: one platform, multiple projects
The model that scales. A single platform hosts multiple distinct documentation projects that share a navigation shell but maintain separate content spaces, separate ownership, and optionally separate search indexes.
✅ What works: users see one doc site, but each product has its own clearly bounded context. The navigation shell makes it possible to move between products without losing orientation. Shared content (authentication concepts, rate limit tables, error code references) lives in one place and gets included or linked — never duplicated.
This is the structure large developer platforms converge on. Stripe’s docs distinguish between “Payments,” “Billing,” “Connect,” and “Radar” in the top-level nav — each its own context, all inside one shell. Twilio separates “Messaging,” “Voice,” and “Email” in the same way. The pattern is not accidental.
The right model: one platform, multiple projects
Federated docs sounds simple to describe and is genuinely difficult to implement without the right tooling. The key principle is separating the content layer from the navigation layer.
Each product gets its own content space — its own directory, its own CODEOWNERS assignment, its own review gate:
docs/
├── _shared/
│ ├── authentication.md # one canonical auth guide
│ ├── rate-limits.md # one canonical rate limits page
│ └── error-codes.md
├── products/
│ ├── api/
│ │ ├── getting-started.md
│ │ └── reference/
│ ├── sdk/
│ │ ├── getting-started.md
│ │ └── platforms/
│ ├── cli/
│ │ └── commands.md
│ └── dashboard/
│ └── overview.md
└── nav.config.yml # navigation structure, separate from content
The navigation layer (nav.config.yml) defines what appears in the sidebar and in what order — independently of where content files live. The product getting-started pages link to the shared authentication guide rather than duplicating it. The shared content is the single canonical source; the product pages are consumers.
This structure allows each team to own and deploy their product’s content independently. The API team can merge and publish without waiting for the SDK team. The platform team owns _shared/, and changes to shared content go through a separate review process.
One threshold to keep in mind: this structure has overhead. If you have one product and a team of two writers, a federated structure will slow you down. If you have two or more products and four or more regular contributors, it will save you more time than it costs within the first quarter.
Navigation and cross-linking — letting users move between products without getting lost
The federated structure only works if the navigation shell is well-designed. A user should always know which product context they are in, and should be able to switch to another product without losing confidence in where they are.
Three navigation patterns that work across multi-product docs:
Product switcher at the top level. A horizontal tab bar or dropdown at the top of the sidebar lets users select which product they are viewing. The sidebar content below changes, but the overall shell — search, header, branding — stays constant. Users learn one navigation model, not four.
Cross-product contextual links. When page content references something in another product, link it explicitly: “This endpoint returns the same error codes documented in the API reference.” Don’t rely on users finding the other page through the nav; surface the connection where they need it.
A shared search index with product filtering. Search that spans all products but lets users narrow to the one they care about eliminates most of the “wrong product” support tickets. A user searching “rate limits” should find the canonical shared page first, not four product-specific approximations of the same content.
Cross-linking is where teams most commonly underinvest. They build the navigation structure and assume users will explore. Most won’t. Users follow the path of least resistance from where they land, which is usually a search result or a direct link from an error message. If that path doesn’t cross-link to related context in other products, the user stays in one silo — and misses the information they actually needed.
Who owns what — assigning responsibility across teams and products
Multi-product documentation fails for the same organizational reason single-product documentation fails: unclear ownership. When nobody is explicitly responsible for a page, nobody updates it.
The ownership model for federated docs:
| Content area | Owner | Review requirement |
|---|---|---|
| Product A reference docs | Product A engineering | Automated from spec or PR review |
| Product A guides | Product A technical writer | Engineering factual review |
| Product B reference docs | Product B engineering | Automated from spec or PR review |
| Product B guides | Product B technical writer | Engineering factual review |
Shared content (_shared/) | Platform / docs lead | Cross-team review — both products sign off |
| Navigation config | Docs lead | Any change requires docs team approval |
Encode this in a CODEOWNERS file so reviews are assigned automatically:
# .github/CODEOWNERS
docs/products/api/ @api-team @api-docs-writer
docs/products/sdk/ @sdk-team @sdk-docs-writer
docs/products/cli/ @platform-team
docs/_shared/ @docs-lead @api-team @sdk-team
docs/nav.config.yml @docs-lead
The critical rule: no one team should be able to merge changes to _shared/ or nav.config.yml without sign-off from the docs lead. Shared content that drifts or navigation that changes unilaterally creates exactly the coherence problem the federated model was designed to prevent.
A practical addition: quarterly content reviews per product, not per page. Assign each product’s docs a 30-minute review slot every quarter. The engineering team lead and the technical writer for that product spend the slot opening every top-level page and checking for accuracy. This sounds lightweight because it is — the goal is to catch obvious staleness before users do, not to audit every sentence.
Teams that define this calendar event as a recurring obligation and assign it as an engineering responsibility (not a docs-team responsibility) keep their content current. Teams that treat it as optional let months pass between reviews and then wonder why support tickets are rising.
How GitDocAI handles multi-product from day one
The hardest part of the federated model operationally is keeping each product’s reference content in sync with its codebase — because you now have two or more codebases evolving at independent velocities.
GitDocAI is built around the repository as the source of truth. You connect each product’s repository separately, define which docs paths belong to which product, and the platform monitors every push. When a code change in the API repo touches a documented endpoint, it flags the corresponding API docs page — not the SDK page, not the CLI page. The ownership boundaries you define in your repository are the same boundaries GitDocAI enforces when surfacing pending doc updates.
For shared content, the platform surfaces changes that affect multiple products simultaneously: a rate limit change in the billing service triggers a review flag on the shared rate-limits.md page, not on four duplicated product-specific versions. The single canonical source stays current instead of four copies drifting independently.
Multi-product documentation is a systems problem, not a writing problem. The writing is the easy part — the structure, the ownership model, and the automation layer are what determine whether the docs stay trustworthy as the product line grows.
If you are already managing more than one product and feeling the friction, map your current structure against the ownership table above. The failure is almost always in shared content (duplicated, drifted) or in navigation (too flat, no product context). Both are fixable. The fix is the same: define one canonical source per concept, assign one owner per content area, and wire automation into the paths where content needs to change most often.
GitDocAI keeps each product’s docs in sync with its codebase on every push, without requiring writers to monitor every repository manually. Start free →