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
36 changes: 2 additions & 34 deletions fern/products/docs/pages/navigation/frontmatter.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Use frontmatter to set a variety of page properties and metadata.
---


You can optionally use frontmatter to set each page's title, full slug override, meta description, a URL to suggest edits to the page, and its OpenGraph image. You can also use frontmatter to disable certain page elements like the table of contents, on-page feedback, and page actions.
You can optionally use frontmatter to set each page's title, slug override, meta description, a URL to suggest edits to the page, and its OpenGraph image. You can also use frontmatter to disable certain page elements like the table of contents, on-page feedback, and page actions.

<Tip>
For advanced styling and functionality customizations beyond frontmatter options, see [custom CSS and JavaScript](/docs/customization/custom-css-js).
Expand Down Expand Up @@ -155,41 +155,9 @@ Want to automatically update the `last-updated` field when MDX files change? See
## Slug

<ParamField path="slug" type="string" required={false}>
Overrides the full URL path for the page, starting from the root of your docs site. This takes precedence over any slug defined in docs.yml.
Overrides the page's URL path, replacing the section and folder hierarchy while preserving any product or version prefix. Takes precedence over a slug set in `docs.yml`. See [configuring slugs](/learn/docs/seo/configuring-slugs#override-with-a-frontmatter-slug) for detailed examples, including behavior within products and versions.
</ParamField>

For example, if you set `slug: email` in frontmatter, the page will be available at `/email` regardless of its location in the navigation structure.

There are two ways to set a page's URL slug:

1. Using `slug` in docs.yml, which is relative to the page's location in the navigation:
<CodeBlock title='docs.yml'>
```yaml
navigation:
- tab: overview
layout:
- section: Support
contents:
- page: Email Us
path: ./pages/email-us.mdx
slug: email # Results in /overview/support/email
```
</CodeBlock>

2. Using `slug` in frontmatter, which overrides everything and sets the absolute path from the root:
<CodeBlock title='email-us.mdx'>
```mdx
---
slug: email # Results in /email (ignores navigation structure)
---
```
</CodeBlock>

The key difference is:
- A slug in docs.yml is relative to the page's location in the navigation structure
- A slug in frontmatter is absolute and ignores the navigation structure completely


## Edit this page

<ParamField path="edit-this-page-url" type="string" required={false}>
Expand Down
25 changes: 23 additions & 2 deletions fern/products/docs/pages/navigation/navigation.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Sections, pages, and folders
subtitle: Organize your sidebar navigation structure in `docs.yml`
description: Configure the sidebar navigation for your Fern documentation site, including sections, pages, folders, icons, and links.
description: Configure the sidebar navigation for your Fern documentation site, including sections, pages, folders, URL slugs, icons, and links.
max-toc-depth: 3
---

Expand Down Expand Up @@ -74,6 +74,8 @@ navigation:
```
{/* <!-- vale on --> */}

Sections also support [`slug` and `skip-slug`](/learn/docs/seo/configuring-slugs) to customize URL paths.

### Add a page

Create an `.md` or `.mdx` file, then add a `page` entry to a section's `contents` with the file path.
Expand Down Expand Up @@ -114,7 +116,7 @@ navigation:
```

For the pages in a folder, Fern automatically:
- Converts filenames to titles and URL slugs
- Derives titles and [URL slugs](#slugs-and-url-paths) from filenames
- Creates nested sections from subdirectories
- Sorts pages alphabetically
- Uses `index.mdx` or `index.md` files as section overview pages (case-insensitive)
Expand Down Expand Up @@ -158,6 +160,25 @@ navigation:
</ParamField>
</Accordion>

## Slugs and URL paths

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] reported by reviewdog 🐶
[FernStyles.Headings] 'Slugs and URL paths' should use sentence-style capitalization.


Fern builds each page's URL by combining slugs from every level of its navigation hierarchy — section, folder, tab, version, and product. Each level gets an auto-generated slug from its display name, or from the filename for [folder-based navigation](#add-a-folder). You can [rename a slug, skip a level, or override the path in a page's frontmatter](/learn/docs/seo/configuring-slugs).

```yaml docs.yml
navigation:
- section: Get Started # slug renamed to "start"
slug: start
contents:
- section: Guides # skipped — omitted from the URL
skip-slug: true
contents:
- page: Quickstart # slug renamed to "quick"
slug: quick
path: ./pages/quickstart.mdx
```

The **Quickstart** page is hosted at `/start/quick`. The renamed section and page slugs apply, and the skipped **Guides** slug drops out of the path.

## Hiding content

To hide a page, folder, or section, add `hidden: true`. Hidden content (including all pages within a folder) is still accessible via direct URL but is excluded from search and won't be indexed.
Expand Down
103 changes: 71 additions & 32 deletions fern/products/docs/pages/seo/configuring-slugs.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
---
title: Customizing slugs within your site
title: Configuring slugs
description: Customize URL paths in your Fern documentation site. Rename slugs for pages, sections, tabs, landing pages, and subheadings, or skip them entirely.
---

By default, Fern generates the slug of a page based on the navigation structure in the `docs.yml` file. Each navigation item — sections, pages, tabs, versions, and products — gets a slug derived from its display name by lowercasing and replacing spaces with hyphens. Special characters such as parentheses are stripped.

By default, Fern generates the slug of a page based on the navigation structure in the `docs.yml` file.
For [folder-based navigation](/learn/docs/configuration/navigation#add-a-folder), page slugs are derived from filenames rather than display names.

| Navigation item | Slug derived from | Example | Auto-generated slug |
|---|---|---|---|
| Section | `section` name | `Key Concepts` | `key-concepts` |
| Page | `page` name | `Quick Start` | `quick-start` |
| Folder | Directory name or `title` | `api-guides` | `api-guides` |
| Tab | `display-name` | `API Reference` | `api-reference` |
| Version | `display-name` | `v3 (Latest)` | `v-3-latest` |
| Product | `display-name` | `My Product` | `my-product` |

<AccordionGroup>
<Accordion title="Example without tabs" defaultOpen>
Expand Down Expand Up @@ -56,7 +66,7 @@ You can customize these default slugs by renaming them or skipping them entirely
Set the `slug` property in `docs.yml` or in a page's frontmatter to customize the URL path.

### Modify a page or section slug
To modify the slug used for a page or section, you can set the `slug` within the `navigation` object.
To modify the slug used for a page or section, set the `slug` within the `navigation` object.

```yaml docs.yml {3, 6}
navigation:
Expand All @@ -72,7 +82,7 @@ In the example above, the **Welcome** page would be hosted at `plantstore.docs.b

### Modify a tab slug

To modify the slug used for a tab, you can set the `slug` within the `tabs` object.
To modify the slug used for a tab, set the `slug` within the `tabs` object.

```yaml docs.yml {4}
tabs:
Expand All @@ -94,40 +104,16 @@ navigation:
In the example above, the **Welcome** page would be hosted at `plantstore.docs.buildwithfern.com/guides/get-started/welcome`.

### Modify a landing page's slug
To modify the slug used for a landing page, you can set the `slug` within the `landing-page` object.
To modify the slug used for a landing page, set the `slug` within the `landing-page` object.

```yaml title="docs.yml" {4}
landing-page:
page: Page Title
path: path/to/landing-page.mdx
slug: /welcome
```
### Rename subheading slugs

### Override a page's slug with frontmatter

Frontmatter slugs take precedence over slugs generated or set in `docs.yml`, giving you full control over a page's URL.

```yaml title="docs.yml"
navigation:
- section: Get Started
slug: start
contents:
- page: Quickstart
path: ./docs/pages/quickstart.mdx
```

With this configuration, the page would normally be at `plantstore.docs.buildwithfern.com/start/quickstart`. To override this, set `slug` in the page's frontmatter:

```markdown title="quickstart.mdx" {2}
---
title: Quickstart
slug: start-up
---
```

The page is now available at `plantstore.docs.buildwithfern.com/start/start-up` instead. See [frontmatter configuration](/learn/docs/configuration/page-level-settings#slug) for more details.

### Renaming slugs for subheadings
By default, deep links to subheadings are generated by appending a `#` and the subheading title (converted to `kebab-casing-convention`) onto the page URL.

```yaml docs.yml
Expand All @@ -138,7 +124,7 @@ navigation:
path: ./docs/pages/welcome.mdx
```

```markdown welcome.mdx
```jsx welcome.mdx
...

## Frequently Asked Questions
Expand All @@ -149,12 +135,65 @@ The link to this section will be available at `plantstore.docs.buildwithfern.com

To rename the slug of the subheading, add the desired slug:

```markdown welcome.mdx
```jsx welcome.mdx
## Frequently Asked Questions [#faqs]
```

The link to this section will now be available at `plantstore.docs.buildwithfern.com/get-started/welcome#faqs`.

### Override with a frontmatter slug

A `slug` set in `docs.yml` replaces only that item's segment, preserving the parent hierarchy. A `slug` set in page frontmatter replaces the **section and folder hierarchy** for that page, but preserves any product or version prefix.

Use frontmatter `slug` when a page needs a short, memorable URL independent of its sidebar position (e.g., a top-level quickstart, a campaign landing page, or a page that moved but must keep its old URL).

```yaml title="docs.yml" {3, 6}
navigation:
- section: Get Started
slug: start
contents:
- page: Quickstart
slug: quick
path: ./docs/pages/quickstart.mdx
```

With only `docs.yml` slugs, the page URL is `plantstore.docs.buildwithfern.com/start/quick` — the hierarchy is preserved. To replace that hierarchy and set the page's path directly, set `slug` in the page's frontmatter:

```markdown title="quickstart.mdx"
---
slug: quickstart
---
```

The page is now at `plantstore.docs.buildwithfern.com/quickstart`, bypassing the section hierarchy. The page still appears in the sidebar under "Get Started", but its URL no longer reflects that structure.

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] reported by reviewdog 🐶
[FernStyles.Current] Avoid time-relative terms like 'now' that become outdated


#### Behavior with products and versions

When a page lives inside a [product](/learn/docs/configuration/navigation#add-a-product) or [version](/learn/docs/configuration/navigation#add-a-version), setting a frontmatter slug replaces only the section/folder portion of the URL. The product and version slugs are always preserved.

```yaml title="docs.yml"
products:
- display-name: Platform
slug: platform
navigation:
- tab: guides
layout:
- section: Get Started
contents:
- page: Quickstart
path: ./docs/pages/quickstart.mdx
```

```markdown title="quickstart.mdx"
---
slug: quickstart
---
```

The resulting URL is `plantstore.docs.buildwithfern.com/platform/quickstart` — **not** `/quickstart`. The product slug `platform` is retained; only the section and tab hierarchy is bypassed.

The same applies to versions: a page in version "v2" of product "platform" with frontmatter `slug: quickstart` resolves to `/platform/v2/quickstart`. To move a page to the absolute root of your docs, place it outside any product or version in your navigation structure.

## Skipping slugs
To ignore a tab or section when generating the slug, simply indicate `skip-slug: true`.

Expand Down
Loading