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
5 changes: 3 additions & 2 deletions fern/products/docs/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,9 @@ navigation:
slug: seo
collapsed: true
contents:
- page: Setting SEO metadata
path: ./pages/seo/metadata.mdx
- page: SEO overview
path: ./pages/seo/seo-overview.mdx
slug: overview
- page: Configuring slugs
path: ./pages/seo/configuring-slugs.mdx
- page: Redirects
Expand Down
294 changes: 294 additions & 0 deletions fern/products/docs/pages/seo/seo-overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
---
title: SEO overview
description: Configure SEO metadata, canonical tags, and social sharing for your Fern documentation site. Learn about meta titles, descriptions, Open Graph tags, and Twitter Cards.
---

Fern automatically generates SEO metadata for every page in your documentation site. Search engines and social media previews work out of the box with no configuration required.

When you want to customize SEO settings, you can set defaults at the site level in `docs.yml` or override them on individual pages using frontmatter. Keep titles between 50-60 characters and descriptions between 150-160 characters for optimal display.

<Tabs>
<Tab title="Meta title & description">

## Meta title and description

The meta title appears in browser tabs and search engine results. The meta description provides a summary that search engines display below the title.

### How Fern generates metadata

Fern looks for metadata values in this order:

1. **Page frontmatter** - Custom SEO values for a specific page
2. **Site-level `docs.yml`** - Default SEO values for all pages
3. **Automatic defaults** - Generated from your page's existing title, description, etc.

### Setting meta title

The HTML `<title>` tag is generated from your page's `title` frontmatter field by default. To set a different title for search engines, use the `headline` field:

<CodeBlock title="quickstart.mdx">
```yaml
---
title: Quickstart
headline: "PlantStore API Quickstart Guide | Developer Documentation"
---
```
</CodeBlock>

The `headline` field overrides the `<title>` tag that search engines see, which is useful for addressing duplicate title issues in your SEO report.

### Setting meta description

The meta description is pulled from your page's `description`, `subtitle`, or `excerpt` frontmatter fields:

<CodeBlock title="quickstart.mdx">
```yaml
---
title: Quickstart
description: "Learn how to integrate with PlantStore's API to manage plant inventory, process orders, and track shipments."
---
```
</CodeBlock>

### Site-level defaults

Set default metadata for your entire site in `docs.yml`:

<CodeBlock title="docs.yml">
```yaml
metadata:
og:title: "PlantStore Developer Documentation"
og:description: "Build with PlantStore's suite of APIs and SDKs. Manage inventory, process orders, and access plant data."
```
</CodeBlock>

</Tab>
<Tab title="Canonical tags">

## Canonical tags

Canonical tags tell search engines which URL is the authoritative version of a page, preventing duplicate content issues.

### Self-referencing canonicals

Fern automatically generates self-referencing canonical URLs for every page based on the page's slug. This is the default behavior and requires no configuration.

For example, a page at `plantstore.docs.buildwithfern.com/guides/quickstart` automatically includes:

```html
<link rel="canonical" href="https://plantstore.docs.buildwithfern.com/guides/quickstart" />
```

### Overriding canonical URLs

To manually set a canonical URL for a specific page, use the `canonical-url` frontmatter field:
Copy link
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 🐶
[Microsoft.URLFormat] Use 'of' (not 'for') to describe the relationship of the word URL to a resource.


<CodeBlock title="quickstart.mdx">
```yaml
---
title: Quickstart
canonical-url: https://docs.plantstore.dev/guides/quickstart
---
```
</CodeBlock>

The canonical URL must be a full URL including the protocol (e.g., `https://`).

### Site-level canonical host

To set the canonical host for your entire site, use the `canonical-host` metadata field in `docs.yml`:

<CodeBlock title="docs.yml">
```yaml
metadata:
canonical-host: https://docs.plantstore.dev
```
</CodeBlock>

This sets the host used for canonical URLs and other metadata tags like the sitemap. By default, Fern uses the URL defined in your `instances` configuration.

</Tab>
<Tab title="Social metadata">

## Social metadata

Social metadata controls how your pages appear when shared on platforms like LinkedIn, Slack, Discord, and Twitter/X.

### Open Graph tags
Copy link
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] 'Open Graph tags' should use sentence-style capitalization.


Open Graph (OG) tags control previews on LinkedIn, Slack, Discord, and other platforms. Fern automatically generates these tags from your page content, but you can customize them.

#### Page-level Open Graph settings
Copy link
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] 'Page-level Open Graph settings' should use sentence-style capitalization.


Set Open Graph metadata in your page's frontmatter:

<CodeBlock title="quickstart.mdx">
```yaml
---
title: Quickstart
og:site_name: PlantStore Developer Documentation
og:title: "PlantStore API Quickstart Guide"
og:description: "Learn how to integrate with PlantStore's API to manage plant inventory and process orders."
og:image: https://plantstore.dev/images/api-docs-banner.png
og:image:width: 1200
og:image:height: 630
og:locale: en_US
og:url: https://docs.plantstore.dev/guides/quickstart
---
```
</CodeBlock>

#### Site-level Open Graph settings
Copy link
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] 'Site-level Open Graph settings' should use sentence-style capitalization.


Set default Open Graph metadata for your entire site in `docs.yml`:

<CodeBlock title="docs.yml">
```yaml
metadata:
og:site_name: "PlantStore Developer Documentation"
og:title: "PlantStore Developer Platform | Plant Management APIs"
og:description: "Build with PlantStore's suite of APIs and SDKs. Manage inventory, process orders, and access plant data."
og:url: "https://docs.plantstore.dev"
og:image: "https://plantstore.dev/images/docs-social-card.png"
og:image:width: 1200
og:image:height: 630
og:locale: "en_US"
og:logo: "https://plantstore.dev/images/logo.png"
```
</CodeBlock>

### Twitter Card tags
Copy link
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] 'Twitter Card tags' should use sentence-style capitalization.


Twitter Card tags control how your pages appear when shared on Twitter/X.

#### Page-level Twitter settings
Copy link
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] 'Page-level Twitter settings' should use sentence-style capitalization.


<CodeBlock title="quickstart.mdx">
```yaml
---
title: Quickstart
twitter:card: summary_large_image
twitter:site: "@PlantStoreAPI"
twitter:title: "PlantStore API Quickstart Guide"
twitter:description: "Learn how to integrate with PlantStore's API to manage plant inventory."
twitter:image: https://plantstore.dev/images/twitter-card.png
---
```
</CodeBlock>

#### Site-level Twitter settings
Copy link
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] 'Site-level Twitter settings' should use sentence-style capitalization.


<CodeBlock title="docs.yml">
```yaml
metadata:
twitter:title: "PlantStore Developer Platform Documentation"
twitter:description: "Integrate plant management, inventory, and order processing into your applications."
twitter:handle: "@PlantStoreDev"
twitter:image: "https://plantstore.dev/images/twitter-card.png"
twitter:site: "@PlantStore"
twitter:card: "summary_large_image"
```
</CodeBlock>

The `twitter:card` field accepts these values: `summary`, `summary_large_image`, `app`, or `player`.

</Tab>
<Tab title="URL best practices">
Copy link
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] 'URL best practices' should use sentence-style capitalization.


## URL best practices

Well-structured URLs improve SEO and user experience. Fern automatically generates clean URLs from your navigation structure.

### URL formatting
Copy link
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] 'URL formatting' should use sentence-style capitalization.


Fern follows these URL best practices by default:

- **Lowercase**: All URLs are automatically converted to lowercase
- **Hyphen-separated**: Words in slugs are separated by hyphens (not underscores)
- **No special characters**: Special characters and spaces are removed or converted
- **Clean paths**: URLs use clean directory-style paths (e.g., `/guides/quickstart`)

### Customizing slugs

You can customize URL paths using the `slug` property in `docs.yml` or in page frontmatter. See [Configuring slugs](/learn/docs/seo/configuring-slugs) for details.

<CodeBlock title="docs.yml">
```yaml
navigation:
- section: Get Started
slug: guides
contents:
- page: Welcome
slug: intro
path: ./docs/pages/welcome.mdx
```
</CodeBlock>

This creates the URL `plantstore.docs.buildwithfern.com/guides/intro`.

### Redirects

When you rename or move pages, set up redirects to preserve SEO value and avoid broken links. See [Redirects](/learn/docs/seo/redirects) for configuration details.

<CodeBlock title="docs.yml">
```yaml
redirects:
- source: "/old-path"
Copy link
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 'old' that become outdated

destination: "/new-path"
- source: "/old-folder/:slug"
Copy link
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 'old' that become outdated

destination: "/new-folder/:slug"
```
</CodeBlock>

### Indexing control

Control whether search engines index specific pages using the `noindex` and `nofollow` frontmatter fields:

<CodeBlock title="internal-page.mdx">
```yaml
---
title: Internal documentation
noindex: true
nofollow: true
---
```
</CodeBlock>

Setting `noindex: true` excludes the page from search engine indexes and from [llms.txt](/learn/docs/ai-features/llms-txt) endpoints.

</Tab>
</Tabs>

## What Fern automatically generates

For every page, Fern creates these SEO tags in your HTML:

<AccordionGroup>
<Accordion title="HTML meta tags">
- `<title>` tag with site-wide suffix (e.g., "Page Title | Your Site Name")
- Meta description (pulled from your `description`, `subtitle`, or `excerpt` fields)
- Meta keywords (when you provide them)
- Canonical URL (from your page slug or `canonical-url` override)
- Robots meta tags (`noindex`/`nofollow` when configured)
- Favicon link tag
</Accordion>
<Accordion title="Open Graph tags">
- `og:title`, `og:description`, `og:image` - What appears in social previews
- `og:url` - Canonical URL of the page
- `og:site_name` - Your website name
- `og:locale` - Content language (e.g., "en_US")
- `og:image:width`, `og:image:height` - Image dimensions
</Accordion>
<Accordion title="Twitter Card tags">
- `twitter:title`, `twitter:description`, `twitter:image` - What appears in Twitter/X previews
- `twitter:site`, `twitter:creator` - Your Twitter handles
- `twitter:card` - Card type (e.g., "summary_large_image")
</Accordion>
</AccordionGroup>

## Related pages

- [Configuring slugs](/learn/docs/seo/configuring-slugs) - Customize URL paths for pages and sections
- [Redirects](/learn/docs/seo/redirects) - Set up redirects when moving or renaming pages
- [Page-level settings](/learn/docs/configuration/page-level-settings) - All frontmatter options
- [Site-level settings](/learn/docs/configuration/site-level-settings) - All `docs.yml` options