Skip to content
Open
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
48 changes: 44 additions & 4 deletions fern/snippets/redirects.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
The `redirects` object allows you to redirect traffic from one path to another. You can redirect exact paths or use dynamic patterns with [`regex`](https://www.npmjs.com/package/path-to-regexp) parameters like `:slug` to handle bulk redirects. You can redirect to internal paths within your site or external URLs.
The `redirects` object allows you to redirect traffic from one path to another. You can redirect exact paths or use dynamic patterns with [Path-to-RegExp](https://www.npmjs.com/package/path-to-regexp) parameters like `:slug` to handle bulk redirects. You can redirect to internal paths within your site or external URLs.

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


<CodeBlock title="docs.yml">

```yml
redirects:
# Exact path redirects
Expand All @@ -17,11 +17,17 @@ If your docs are hosted on a subpath (like `buildwithfern.com/learn`), include t
destination: "/new-location"
permanent: false # Use 307 (temporary) instead of 308 (permanent)

# Regex-based redirects
# Pattern-based redirects
- source: "/old-folder/:slug" # Matches single segments: /old-folder/foo
destination: "/new-folder/:slug"
- source: "/old-folder/:slug*" # Matches multiple segments: /old-folder/foo/bar/baz
destination: "/new-folder/:slug*"
destination: "/new-folder/:slug*"

# Named capture groups with regex patterns
- source: "/release-notes/:year(\\d{4})-{0}:month(\\d{1,2})"
destination: "/docs/release-notes/:year/:month/1"
- source: "/api/v:version(\\d+)/:endpoint*"
destination: "/api-reference/:version/:endpoint*"
```
</CodeBlock>

Expand All @@ -41,6 +47,40 @@ If your docs are hosted on a subpath (like `buildwithfern.com/learn`), include t
`true` or `false` - default is `true`. If `true`, will use the 308 status code which instructs clients/search engines to cache the redirect forever. If `false`, will use the 307 status code which is temporary and is not cached.
</ParamField>

### Advanced patterns

You can define named capture groups with regex patterns and reuse them in destination URLs:

<CodeBlock title="docs.yml">

```yml
redirects:
# Match 4-digit years
- source: "/blog/:year(\\d{4})/:slug*"
destination: "/archive/:year/:slug*"

# Match dates with literal separator
- source: "/posts/:year(\\d{4})-{0}:month(\\d{2})-{0}:day(\\d{2})"
destination: "/blog/:year/:month/:day"

# Match numeric IDs only
- source: "/user/:id(\\d+)"
destination: "/users/:id/profile"
```
</CodeBlock>

<Accordion title="Pattern syntax">

| Pattern | Description |
|---------|-------------|
| `:name` | Captures a single path segment |
| `:name*` | Captures zero or more segments |
| `:name(\\d+)` | Captures digits only |
| `:name(\\d{4})` | Captures exactly 4 digits |
| `{0}` | Literal character delimiter between parameters |

</Accordion>

### Best practices

For optimal site performance, only add redirects when necessary. Avoid using redirects for behavior that Fern already handles automatically, such as 404 handling and version routing.
Expand Down