Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions fern/products/docs/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ navigation:
path: ./pages/preview-publish/publishing-your-docs.mdx
- page: Setting up your domain
path: ./pages/preview-publish/setting-up-your-domain.mdx
- page: Multi-source docs
path: ./pages/preview-publish/multi-source.mdx
- section: Customization
collapsed: true
contents:
Expand Down
20 changes: 20 additions & 0 deletions fern/products/docs/pages/changelog/2026-04-30.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
tags: ["configuration"]
---

## Multi-source docs

Multi-source docs lets each team publish independently to a shared custom domain — for example, [docs.nvidia.com](https://docs.nvidia.com) spans sub-paths like `/nvcf`, `/brev`, and `/aiperf`, each owned by a different product team and repository.

Set `multi-source: true` on the instance and reference a [global theme](/learn/docs/customization/global-themes) for consistent branding across repositories.

```yaml docs.yml
global-theme: my-org-theme

instances:
- url: example.docs.buildwithfern.com/product-a
custom-domain: docs.example.com/product-a
multi-source: true
```

<Button intent="none" outlined rightIcon="arrow-right" href="/learn/docs/preview-publish/multi-source">Read the docs</Button>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: An overview of the file and folder structure of a Fern Docs project
---


This page provides an overview of the file and folder structure of a Fern Docs project.
This page provides an overview of the file and folder structure of a Fern Docs project. If you're spreading docs across multiple repositories that publish to the same domain, see [Multi-source docs](/learn/docs/preview-publish/multi-source).

## Directory structure

Expand Down
4 changes: 4 additions & 0 deletions fern/products/docs/pages/navigation/site-level-settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ instances:
You can use audiences to control which versions and products appear in each documentation instance, enabling you to create separate sites for different user groups. Content is included when its audience tag matches the instance audience. Content without an audience tag is included by default. Learn more about configuring instance audiences for [products and/or versions](/docs/configuration/products#add-instance-audiences).
</ParamField>

<ParamField path="instances.multi-source" type="boolean" required={false} default={false} toc={true}>
When `true`, the CLI uses basepath-aware publishing so multiple independent repositories can publish to the same custom domain with different basepaths. The `url` and `custom-domain` must share the same basepath when this is enabled. Learn more about [multi-source docs](/learn/docs/preview-publish/multi-source).
</ParamField>

## Colors configuration

Configure your documentation's color palette for both light and dark modes. Only `accent-primary` is required — all other colors have sensible defaults. These colors are also automatically available as [CSS custom properties](/learn/docs/customization/custom-css-js#built-in-css-color-variables) in your custom stylesheets.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
208 changes: 208 additions & 0 deletions fern/products/docs/pages/preview-publish/multi-source.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
---
title: Multi-source docs
subtitle: Let multiple teams publish to the same docs site from their own repositories.
description: Learn how to set up multi-source documentation so independent teams can publish to shared domains with consistent branding using Fern.
---

<Markdown src="/snippets/enterprise-plan.mdx" />

Multi-source documentation lets multiple teams publish to the same custom domain from independent repositories. Each repository has its own `docs.yml` and content, while a shared [global theme](/learn/docs/customization/global-themes) keeps branding consistent across every sub-path.

## How it works

Each repository owns a unique basepath on the shared domain. Running `fern generate --docs` in one repository updates only its sub-path — every other sub-path is untouched.

Three pieces of configuration make this work:

1. **`multi-source: true`** set on the instance in each repository's `docs.yml`, with `url` and `custom-domain` ending in the same basepath.
2. **[Global themes](/learn/docs/customization/global-themes)**, referenced by name in each `docs.yml`, deliver shared branding from a central source.
3. **Multi-repo settings** in the [Fern Dashboard](https://dashboard.buildwithfern.com) control the domain's default path and search/Ask AI scope.

For example, NVIDIA's docs are split across multiple independent repositories, each publishing to its own sub-path on `docs.nvidia.com`:

- [docs.nvidia.com/nvcf](https://docs.nvidia.com/nvcf)
- [docs.nvidia.com/brev](https://docs.nvidia.com/brev)
- [docs.nvidia.com/aiperf](https://docs.nvidia.com/aiperf)
- [docs.nvidia.com/nemo/curator](https://docs.nvidia.com/nemo/curator)

Each sub-path is published independently, but end users see a single unified site. The root `docs.nvidia.com` itself is a separate site outside the Fern setup — multi-source covers only the sub-paths. A Fern-published landing page is optional ([example](#example-setup-with-a-homepage-and-three-teams)), and any combination of sub-paths works, including just two.

## Set up multi-source docs

<Steps>

<Step title="Create a control repository for the global theme">

The control repository is a dedicated Fern project whose only job is to house your global theme — the shared logo, colors, fonts, layout, and site-level settings that every team repository will inherit. Define those settings in its `docs.yml`, then export and upload the theme:

```bash
fern docs theme export
fern docs theme upload --name my-org-theme
```

See [Global themes](/learn/docs/customization/global-themes) for the full setup guide and the list of fields the theme controls.

</Step>

<Step title="Configure each repository">

Each sub-path has its own repository (typically owned by a different team), separate from the control repository in Step 1. In each repository's `docs.yml`:

- Reference the global theme by name: `global-theme: my-org-theme`.
- Declare an instance with `multi-source: true` and a unique basepath on the shared domain. That basepath must appear at the end of both `url` and `custom-domain`.

For example, here are two repositories on the same shared domain — one at `/product-a`, one at `/product-b`:

<Tabs>
<Tab title="Product A repo">
```yaml docs.yml
global-theme: my-org-theme

instances:
- url: example.docs.buildwithfern.com/product-a
custom-domain: docs.example.com/product-a
multi-source: true
```
</Tab>
<Tab title="Product B repo">
```yaml docs.yml
global-theme: my-org-theme

instances:
- url: example.docs.buildwithfern.com/product-b
custom-domain: docs.example.com/product-b
multi-source: true
```
</Tab>
</Tabs>

</Step>

<Step title="Publish from each repository">

Each repository publishes independently:

```bash
fern generate --docs
```

Only the sub-path owned by that repository is updated. Every other sub-path is unaffected.

</Step>

<Step title="Configure domain settings in the Dashboard">

Open the [Fern Dashboard](https://dashboard.buildwithfern.com) and select your top-level domain (e.g., `docs.example.com`) — these settings apply to the whole domain, not per sub-path. In the **Settings** tab, navigate to the **Multi-repo settings** card and configure:

- **Default path** *(optional)* — sets where users land when they visit the bare root of your domain. Set this when a Fern-managed page should serve as the root: for example, if your homepage lives at the `/home` sub-path, set the default path to `/home` so `docs.example.com` redirects to `docs.example.com/home`. Skip this if the root isn't Fern-managed, like NVIDIA's `docs.nvidia.com` (a separate marketing site outside the Fern setup).
- **Search / Ask AI behavior** — controls how [Ask Fern](/learn/docs/ai-features/ask-fern/overview) and search work across sub-paths.

<Frame>
![Multi-source settings in the Fern Dashboard](./images/multi-repo.png)
</Frame>

Two search modes are available:

- **Hierarchical** — searches under `/subpath` only return results from `/subpath` and below. Use this when each sub-path covers a distinct product and users expect scoped results.
- **Unified** — searches under any sub-path return results from all sub-paths. Use this when the sub-paths are parts of a single product and users benefit from cross-cutting results.

</Step>

</Steps>

## Example: Homepage and three sub-paths

This is the alternative shape to NVIDIA's setup: a Fern-managed homepage that serves as the root, with three product teams each on their own sub-path. Use this pattern when the root should be a landing page or product selector instead of pointing somewhere outside Fern.

The setup uses four `fern/` projects — a homepage at `/home` plus one per team at `/seeds`, `/greenhouses`, and `/nursery`. All four share the same global theme (`plantstore-theme`) and set `multi-source: true`; they differ only in their basepath:

<Tabs>
<Tab title="Homepage">
```yaml Homepage — docs.yml
global-theme: plantstore-theme

instances:
- url: plantstore.docs.buildwithfern.com/home
custom-domain: docs.plantstore.com/home
multi-source: true

navigation:
- page: Home
path: ./pages/home.mdx
```

The homepage `home.mdx` can use cards to direct users to each team's docs:

```jsx home.mdx
<CardGroup>
<Card title="Seeds" icon="fa-regular fa-seedling" href="https://docs.plantstore.com/seeds">
Seed catalog and germination guides.
</Card>
<Card title="Greenhouses" icon="fa-regular fa-warehouse" href="https://docs.plantstore.com/greenhouses">
Climate control and monitoring.
</Card>
<Card title="Nursery" icon="fa-regular fa-leaf" href="https://docs.plantstore.com/nursery">
Plant care and propagation.
</Card>
</CardGroup>
```
</Tab>
<Tab title="Seeds team">
```yaml Seeds team — docs.yml
global-theme: plantstore-theme

instances:
- url: plantstore.docs.buildwithfern.com/seeds
custom-domain: docs.plantstore.com/seeds
multi-source: true

navigation:
- section: Getting started
contents:
- page: Overview
path: ./pages/overview.mdx
```
</Tab>
<Tab title="Greenhouses team">
```yaml Greenhouses team — docs.yml
global-theme: plantstore-theme

instances:
- url: plantstore.docs.buildwithfern.com/greenhouses
custom-domain: docs.plantstore.com/greenhouses
multi-source: true

navigation:
- section: Getting started
contents:
- page: Overview
path: ./pages/overview.mdx
```
</Tab>
<Tab title="Nursery team">
```yaml Nursery team — docs.yml
global-theme: plantstore-theme

instances:
- url: plantstore.docs.buildwithfern.com/nursery
custom-domain: docs.plantstore.com/nursery
multi-source: true

navigation:
- section: Getting started
contents:
- page: Overview
path: ./pages/overview.mdx
```
</Tab>
</Tabs>

## Properties

<ParamField path="instances.multi-source" type="boolean" required={false} default={false}>
When `true`, the CLI uses basepath-aware publishing so multiple repositories can coexist under one custom domain. The `url` and `custom-domain` must share the same basepath when this is enabled.
</ParamField>

<ParamField path="global-theme" type="string" required={false}>
The name of a [global theme](/learn/docs/customization/global-themes) to apply. The CLI fetches the named theme from Fern's registry at publish time and merges its branding fields into the local `docs.yml`. See [What the theme controls](/learn/docs/customization/global-themes#what-the-theme-controls) for the full list of fields.
</ParamField>
Loading