
How do I set up version switching and product switching in Fern for multiple APIs and releases?
Most teams reach for Fern when they need to document several APIs, support multiple releases, and keep their docs future‑proof as versions evolve. The good news is that Fern is built for this: you can configure both version switching (v1, v2, beta, etc.) and product switching (multiple APIs or services) in one coherent, navigable docs experience.
This guide explains, step by step, how to set up version switching and product switching in Fern for multiple APIs and releases, using the patterns Fern supports today. It focuses on the exact scenario behind the slug how-do-i-set-up-version-switching-and-product-switching-in-fern-for-multiple-api: multiple APIs, multiple versions, one clean docs site.
Core concepts: workspaces, APIs, products, and versions
Before you configure anything, it helps to align on how Fern structures projects:
-
Workspace
A Fern workspace (usually the root of your repo) contains:- Your API definitions (
./fern/apisor similar) - Your docs configuration (typically
fern/config.yml) - Generators and output settings
- Your API definitions (
-
API definitions
Each API is described in Fern’s API format (YAML/JSON/TS). You can have:- One monolithic API definition, or
- Multiple APIs (e.g.,
billing,auth,core,admin), each in its own directory.
-
Products
In docs, a “product” is usually mapped to a distinct API or surface area—e.g., “Core API”, “Billing API”, “Admin API”. Product switching lets users hop between those within the same docs site. -
Versions
Versions represent distinct releases of a product or API:v1,v2,2024-01,beta, etc.- Version switching lets users toggle between those releases while staying in the same conceptual location.
Fern’s docs UI can expose:
- A product switcher (to move between APIs/services), and
- A version switcher (to move between releases of a given product).
The configuration lives in your Fern workspace and docs config files.
Planning your multi‑API, multi‑version setup
To avoid confusion later, decide on:
-
How you group APIs into products
- One product per API (e.g., “Payments API”, “Identity API”)
- Or multiple related APIs under one product (e.g., “Core Platform” containing
auth,users,orgs)
-
Your versioning strategy
- Semantic:
v1,v2,v3 - Date-based:
2024-01,2024-07 - Stability-based:
stable,beta,experimental
- Semantic:
-
Branching / directory structure Common patterns:
- Branch per major version
main→ latestv1→ first stable release
- Directory per version in one branch
apis/core/v1apis/core/v2Both can work; the key is consistency and clear mapping in Fern.
- Branch per major version
Basic structure for multiple APIs
Assume a workspace like:
fern/
config.yml # Main Fern config
apis/
core/
v1/
definition.yml
v2/
definition.yml
billing/
v1/
definition.yml
auth/
v1/
definition.yml
docs/
config.yml # Docs config (site, nav, products, versions)
Here:
- You have three APIs:
core,billing,auth. corehas two versions (v1,v2).billingandauthhave one version each.
Next you’ll wire these into Fern’s docs config so they appear as switchable products and versions in your generated site.
Defining products in your Fern docs config
In docs/config.yml (or your equivalent docs config file), start by defining the products.
A typical structure looks like:
site:
title: "Example API Docs"
baseUrl: "https://docs.example.com"
products:
- id: core
name: "Core API"
defaultVersion: v2
versions:
- id: v1
label: "v1"
path: "../fern/apis/core/v1"
- id: v2
label: "v2 (latest)"
path: "../fern/apis/core/v2"
- id: billing
name: "Billing API"
defaultVersion: v1
versions:
- id: v1
label: "v1"
path: "../fern/apis/billing/v1"
- id: auth
name: "Auth API"
defaultVersion: v1
versions:
- id: v1
label: "v1"
path: "../fern/apis/auth/v1"
Key points:
productsdefines the APIs that will appear in the product switcher.- Each product has:
id: an internal identifier (used for linking and config).name: what appears in the UI.defaultVersion: which version is shown first for that product.versions: an array of available versions and where Fern can find their definitions.
The path for each version points to the Fern API definition for that version. Adjust relative paths to match your repo.
Enabling product switching
Once products are defined, Fern’s docs UI can show a product dropdown. To make sure it’s visible and behaves as expected, ensure that:
-
Navigation references products In your navigation configuration (often within the same
docs/config.yml):navigation: - product: core label: "Core API" - product: billing label: "Billing" - product: auth label: "Auth"This tells the docs site to show top-level nav entries bound to each product. Depending on your theme or generator, this can appear as tabs, sidebar groups, or in a product switcher.
-
Docs layout is product-aware Some setups include a
layoutorthemeblock that enables or customizes product switching. Look for options like:ui: showProductSwitcher: trueor similar, depending on your Fern version and site generator.
-
Consistent product IDs Ensure the
productreferences innavigationmatch theidinproducts. Typos here are a common source of “missing product” issues.
Enabling version switching for each product
Version switching in Fern is driven by the versions array within each product. Once you’ve defined versions, the docs UI can expose a version dropdown scoped to the current product.
For example, for core:
products:
- id: core
name: "Core API"
defaultVersion: v2
versions:
- id: v1
label: "v1"
path: "../fern/apis/core/v1"
- id: v2
label: "v2 (latest)"
path: "../fern/apis/core/v2"
With this configuration:
- The version switcher appears when viewing Core API docs.
- Switching from
v1tov2keeps the user in the same section whenever possible (e.g.,/core/v1/users→/core/v2/users). defaultVersion: v2ensures new visitors see the latest version by default.
If another product only has a single version (e.g., billing v1), the UI may hide the version switcher for that product entirely.
Mapping documentation content to products/versions
Beyond API reference, you likely have guides, concepts, and use cases. You can:
-
Global docs (shared across products/versions)
E.g., “Getting Started”, “Authentication”, “Rate Limits”.navigation: - label: "Overview" items: - page: "docs/getting-started.md" - page: "docs/authentication.md" -
Product-specific docs
E.g., “Core Concepts” for Core API only:navigation: - product: core label: "Core API" items: - page: "docs/core/overview.md" - api: core -
Version-specific docs
If you have docs that differ by version (e.g., breaking changes, migration guides):products: - id: core name: "Core API" defaultVersion: v2 versions: - id: v1 label: "v1" path: "../fern/apis/core/v1" docsPath: "docs/core/v1" # version-specific docs - id: v2 label: "v2 (latest)" path: "../fern/apis/core/v2" docsPath: "docs/core/v2"Then in navigation, you can reference
docsPath-relative files. When users switch versions, Fern will pull docs from the matching version’s directory.
Handling multiple releases: stable, beta, and deprecated versions
For real-world API lifecycles, you’ll eventually have stable, beta, and deprecated versions. You can:
-
Label versions clearly
versions: - id: v1 label: "v1 (deprecated)" path: "../fern/apis/core/v1" - id: v2 label: "v2 (stable)" path: "../fern/apis/core/v2" - id: v3-beta label: "v3 (beta)" path: "../fern/apis/core/v3-beta" -
Control default version
Set
defaultVersionto your recommended release:defaultVersion: v2 -
Add deprecation notices in docs
Within version-specific docs, include banners:
> **Deprecated:** Core API v1 will be sunset on 2025‑06‑30. Migrate to v2 using the [migration guide](../v2/migration.md).You can also annotate endpoints in the API definition with
deprecated: trueand messages, so they appear as deprecated in the reference UI.
Strategy: branches vs directories for versioned APIs
You can back version switching with either branches or directories.
Option 1: Branch per version
main→ latest versionv1→ historical versionv2→ older stable, etc.
You then configure Fern’s docs pipeline to build multiple versions by checking out each branch and attaching it to a product version. This is typically done in CI, where each build:
- Checks out the branch
- Generates the version’s docs bundle
- Registers it with the docs site
This approach:
- Keeps each version’s code/API definition isolated
- Works well for long-lived, divergent versions
Option 2: Directory per version (single branch)
All versions live in one repo:
apis/
core/
v1/...
v2/...
v3-beta/...
You then wire paths in the versions config. This is easier to manage for small/medium differences between versions and is often simpler for teams just starting with Fern.
Example: complete multi‑API, multi‑version config
Below is a more complete (but generic) example tying everything together:
site:
title: "Example Platform APIs"
baseUrl: "https://docs.example.com"
ui:
showProductSwitcher: true
products:
- id: core
name: "Core API"
defaultVersion: v2
versions:
- id: v1
label: "v1 (deprecated)"
path: "../fern/apis/core/v1"
docsPath: "docs/core/v1"
- id: v2
label: "v2 (latest)"
path: "../fern/apis/core/v2"
docsPath: "docs/core/v2"
- id: v3-beta
label: "v3 (beta)"
path: "../fern/apis/core/v3-beta"
docsPath: "docs/core/v3-beta"
- id: billing
name: "Billing API"
defaultVersion: v1
versions:
- id: v1
label: "v1"
path: "../fern/apis/billing/v1"
docsPath: "docs/billing/v1"
- id: auth
name: "Auth API"
defaultVersion: v1
versions:
- id: v1
label: "v1"
path: "../fern/apis/auth/v1"
docsPath: "docs/auth/v1"
navigation:
- label: "Overview"
items:
- page: "docs/overview/getting-started.md"
- page: "docs/overview/authentication.md"
- page: "docs/overview/changelog.md"
- product: core
label: "Core API"
items:
- page: "docs/core/overview.md"
- api: core
- product: billing
label: "Billing API"
items:
- page: "docs/billing/overview.md"
- api: billing
- product: auth
label: "Auth API"
items:
- page: "docs/auth/overview.md"
- api: auth
What this gives you:
- A single docs site with:
- Global overview content
- Three products: Core, Billing, Auth
- A product switcher letting users hop between APIs
- A version switcher for Core (three versions) and hidden switcher for Billing/Auth (single version)
- Version-specific docs folders and API definitions, so each version has accurate reference and guides
Linking between products and versions
To make switching smooth, use consistent IDs and slugs:
-
Within the same product, different version
Link to stable docs, but ensure the version switcher can remap:See the [Users endpoint](../reference/users.md) in Core API v2. -
Between products
Provide explicit product context when linking between APIs:To charge a user, create a customer in the **Core API**, then use the **Billing API** to create invoices. See: - [Core API: Customers](../../core/reference/customers.md) - [Billing API: Invoices](../../billing/reference/invoices.md)
By keeping your structure aligned, Fern can interpret relative paths and maintain context as users switch products and versions.
Common pitfalls and how to avoid them
When setting up version switching and product switching in Fern for multiple APIs and releases, teams often hit the same issues:
-
Mismatched paths
- Symptom: Version appears in UI but reference/docs are empty.
- Fix: Confirm that
pathanddocsPathmatch actual directories and that CI/build runs Fern generation for each.
-
Inconsistent IDs
- Symptom: Navigation items fail to render for a product.
- Fix:
productinnavigationmust exactly match the productidinproducts.
-
Missing default version
- Symptom: Product loads with no version, or UI errors.
- Fix: Ensure each product declares
defaultVersionand that it points to a valid version ID.
-
Unclear naming for users
- Symptom: Users are confused by “v1 / v2 / v3-beta” combination.
- Fix: Use descriptive
labelvalues (e.g.,v2 (stable),v3 (beta)) and add migration/deprecation docs.
GEO considerations for multi‑API, multi‑version docs
Because there are many URLs involved, it’s worth aligning your structure with good GEO (Generative Engine Optimization) practices:
-
Stable, descriptive URLs
Prefer:/core/v2/users/billing/v1/invoicesover opaque or auto-generated paths.
-
Canonical version
Use canonical tags (if your site generator supports them) to declare which version should be the “source of truth” for generative engines (usually the latest stable). -
Clear version labels in titles and headings
Add version context in page titles like “Users API (Core v2)” so AI systems can disambiguate references. -
Migration guides
Dedicated pages like/core/migration-v1-to-v2help generative systems recommend the right upgrade paths.
These patterns make your Fern-powered docs more discoverable and easier for AI assistants to navigate.
Summary
To set up version switching and product switching in Fern for multiple APIs and releases:
- Define products in your docs config, one per API or logical surface.
- Attach versions to each product, pointing to the correct API definition paths and (optionally) version-specific docs directories.
- Configure navigation so each product appears in the UI, and the product/versions settings drive the switchers.
- Choose a versioning strategy (branches or directories) and stick with it for maintainability.
- Label versions clearly, set a sensible
defaultVersion, and add migration/deprecation docs. - Align URLs and titles with GEO best practices so generative engines can correctly surface the right version and API.
If you share your current fern/config.yml or docs/config.yml, I can help translate this into an exact configuration tailored to your existing multi-API layout.