Skip to content
Merged
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
12 changes: 12 additions & 0 deletions fern/products/docs/pages/changelog/2026-08-27.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,15 @@ You can now present a changelog as a blog, with dated entries rendered as cards
</Frame>

<Button intent="none" outlined rightIcon="arrow-right" href="/learn/docs/configuration/changelogs#blog-layout">Read the docs</Button>

## Redirects in separate files

<ChangelogTags>seo, docs.yml</ChangelogTags>

You can now keep redirects in a separate YAML file and reference it from `docs.yml`. You can also split redirects across multiple files.

```yaml docs.yml
redirects: ./redirects.yml
```

<Button intent="none" outlined rightIcon="arrow-right" href="/learn/docs/seo/redirects#keep-redirects-in-separate-files">Read the docs</Button>
10 changes: 8 additions & 2 deletions fern/products/docs/pages/navigation/site-level-settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ navbar-links:
Configure the `primaryAccent` and `background` colors. Learn more about the [`colors` configuration](/learn/docs/getting-started/global-configuration#colors-configuration).
</ParamField>

<ParamField path="redirects" type="list of objects" required={false} toc={true}>
An array of paths you want to configure to permanently redirect to another path. Learn more about the
<ParamField path="redirects" type="list of objects, string, or list of strings" required={false} toc={true}>
A list of redirects, a YAML file path, or a list of YAML file paths. Learn more about the
[`redirects` configuration](/learn/docs/getting-started/global-configuration#redirects-configuration).
</ParamField>

Expand Down Expand Up @@ -268,6 +268,12 @@ redirects:
destination: /new-folder/:slug*
```

To keep redirects in separate files, set `redirects` to one or more YAML file paths:

```yaml docs.yml
redirects: ./redirects.yml
```

<Markdown src="/products/docs/snippets/redirects.mdx" />

## NavBar links configuration
Expand Down
49 changes: 47 additions & 2 deletions fern/products/docs/pages/seo/redirects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Redirects map old URLs to new ones so inbound links and search rankings survive

## Set up redirects

Configure redirects in `docs.yml`, pointing at either internal paths or external URLs. Use an exact path when a single URL moves, and a [pattern](#pattern-syntax) when a path's descendants move with it: an exact `source` matches that one URL and nothing beneath it, so `/old-folder` leaves `/old-folder/page` alone.
Configure redirects to internal paths or external URLs in `docs.yml` or in [separate files](#keep-redirects-in-separate-files) that `docs.yml` references. Use an exact path when a single URL moves, and a [pattern](#pattern-syntax) when a path's descendants move with it: an exact `source` matches that one URL and nothing beneath it, so `/old-folder` leaves `/old-folder/page` alone.

If your docs are hosted on a subpath (like `buildwithfern.com/learn`), include the subpath in both the source and destination paths.

Expand Down Expand Up @@ -55,6 +55,38 @@ Repeat the regular expression in `destination`. A parameter written as `:slug(.*

The optional modifier (`?`) is unsupported. Fern strips each `source` at the first `?` to remove search parameters, so `/old-folder/:slug?` is matched as `/old-folder/:slug`.

## Keep redirects in separate files

Set `redirects` in `docs.yml` to one or multiple YAML file paths:

<Tabs>
<Tab title="One file">
```yaml title="docs.yml"
redirects: ./redirects.yml
```
</Tab>

<Tab title="Multiple files">
```yaml title="docs.yml"
redirects:
- ./redirects/api.yml
- ./redirects/guides.yml
```
</Tab>
</Tabs>

Each file must contain a top-level `redirects` list:

```yaml title="redirects.yml"
redirects:
- source: "/old-path"
destination: "/new-path"
- source: "/old-folder/:slug*"
destination: "/new-folder/:slug*"
```

File paths are relative to `docs.yml`. Fern evaluates the files in the order listed. Use file paths or inline redirect entries, but not both.

## Evaluation order

Redirects are evaluated top-to-bottom and the first match wins, so list specific paths before broader ones:
Expand Down Expand Up @@ -152,6 +184,20 @@ redirects:
destination: /new-path # must differ from `source`
```

### Failed to load redirects: /path/to/redirects.yml does not exist

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [vale] <Microsoft.Contractions> reported by reviewdog 🐶
Use 'doesn't' instead of 'does not'.

Suggested change
### Failed to load redirects: /path/to/redirects.yml does not exist
### Failed to load redirects: /path/to/redirects.yml doesn't exist


`redirects` in `docs.yml` points at a file that isn't on disk. Filepaths resolve relative to `docs.yml`, so `redirects: ./redirects.yml` refers to a file that sits next to it.

### Failed to parse /path/to/redirects.yml: the file must nest the list under a top-level `redirects` key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [vale] <Microsoft.HeadingColons> reported by reviewdog 🐶
Capitalize ': t'.


A redirects file holds a `redirects` key, not a bare list:

```yaml title="redirects.yml"
redirects:
- source: /old
destination: /new
```

### Circular redirect chain detected: /a → /b → /a

Two or more [redirects](/learn/docs/configuration/site-level-settings#redirects-configuration) form a cycle: `/a` redirects to `/b`, and `/b` redirects back to `/a` (directly or through more hops). The browser would bounce between them indefinitely. Point every `source` in the chain at the final destination directly, so no `destination` is itself another `source`.
Expand All @@ -164,4 +210,3 @@ redirects:
destination: /c
```
</llms-only>

Loading