Skip to content

Clarify link behavior, link checking, and redirects validation #5489

Merged
devalog merged 7 commits into
mainfrom
fern/docs-links-clarifications
May 13, 2026
Merged

Clarify link behavior, link checking, and redirects validation #5489
devalog merged 7 commits into
mainfrom
fern/docs-links-clarifications

Conversation

@fern-api
Copy link
Copy Markdown
Contributor

@fern-api fern-api Bot commented May 13, 2026

Summary

Clarify how links resolve in Fern docs and what fern check actually validates locally. Triggered by recurring confusion about:

  1. fern check broken-links local vs deployed — the checker validates against the navigation tree built from local YAML, not the live site, which surfaces unfamiliar warnings during fern docs dev.
  2. Links in versioned docs with shared (common/) content — an absolute path resolves to whichever version is published at that path; the default version is unversioned and other versions live at versioned paths.
  3. fern check redirects (missing-redirects) — what it compares against, why it requires auth, and how to silence the noise during a migration.

Changes

  • `fern/products/docs/pages/component-library/writing-content/markdown-basics.mdx` — Rewrote the Links in Markdown section:

    • Replaced the confusing "relative URL" framing with "published site path" and called out that paths are built from YAML slugs, not file paths and not file-relative paths.
    • Added a Links in versioned docs subsection covering the default-version vs other-version path shapes, with a worked example for a page shared across versions via a `common/` folder. Cross-linked the `` and `` components for inline conditional content.
    • Added a Validate links locally subsection explaining that `fern check` (including the run inside `fern docs dev`) validates against local config, not the deployed site, and pointing to `check.rules.broken-links: warn` for tuning noise during migrations. Cross-linked the Dashboard live link checker.
  • `fern/products/docs/pages/seo/redirects.mdx` — Added a How `missing-redirects` works subsection explaining the check compares against the last published navigation (which is why it requires `fern login` / `FERN_TOKEN`, is skipped on first publish, and won't flag moves inside an un-published batch). Added a `` for migration scenarios with the `check.rules.missing-redirects: warn` escape hatch.

  • `fern/products/cli-api-reference/pages/commands.mdx` — Added one paragraph in the `fern check` accordion clarifying that the command validates against local config and pointing to the Dashboard for live-site checks.

  • `fern/products/docs/snippets/redirects.mdx` — Fixed an inconsistent versioned URL example. Other Fern docs (Versions page, `default-version` snippet) describe versioned paths as version-prefixed (e.g. `/docs/v2/getting-started`); this snippet was using the suffix form (`/docs/getting-started/v2`). Updated to match the rest of the docs.

Requested by: Fern Support

@fern-api fern-api Bot requested a review from devalog as a code owner May 13, 2026 16:01
@fern-api
Copy link
Copy Markdown
Contributor Author

fern-api Bot commented May 13, 2026

Requested by: devin
Slack thread: View conversation


### Validate links locally

[`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check) — including the validation run that fires during `fern docs dev` — checks internal links against the navigation tree built from your **local** `docs.yml` and product YAML files. It does not crawl your live deployed site or follow external URLs. A link that works on the deployed site can still flag locally if your local config doesn't yet contain the destination's slug (and vice versa).
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 🐶
[Microsoft.Contractions] Use 'doesn't' instead of 'does not'.


### How `missing-redirects` works

The check compares the navigation tree built from your **local** config against the navigation tree of your most recently **published** site, then flags any previously-published URL that no longer resolves and is not covered by an entry in `redirects:`. Because it reads the published state, it requires authentication — run [`fern login`](/learn/cli-api-reference/cli-reference/commands#fern-login) first, or set the `FERN_TOKEN` environment variable. The check is skipped when authentication is missing, when the network is unavailable, or on a site's first publish.
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.Hyphens] 'previously-published' doesn't need a hyphen.


### How `missing-redirects` works

The check compares the navigation tree built from your **local** config against the navigation tree of your most recently **published** site, then flags any previously-published URL that no longer resolves and is not covered by an entry in `redirects:`. Because it reads the published state, it requires authentication — run [`fern login`](/learn/cli-api-reference/cli-reference/commands#fern-login) first, or set the `FERN_TOKEN` environment variable. The check is skipped when authentication is missing, when the network is unavailable, or on a site's first publish.
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 🐶
[Microsoft.Contractions] Use 'isn't' instead of 'is not'.

@github-actions
Copy link
Copy Markdown
Contributor

## Catching missing redirects

You can use [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check) to automatically detect pages that were removed or moved without a redirect. Configure the [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration) in `docs.yml` to control its severity.
[`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check) compares your local navigation against the most recently **published** state of your site and flags previously-published URLs that no longer resolve and aren't covered by an entry in `redirects:`. Because it reads the published state, it requires [`fern login`](/learn/cli-api-reference/cli-reference/commands#fern-login) or the `FERN_TOKEN` environment variable, and is skipped on first publish or when unauthenticated. Pages added and moved within the same un-published batch aren't compared.
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.Hyphens] 'previously-published' doesn't need a hyphen.

In [versioned docs](/learn/docs/configuration/versions), the same path lands on a different version depending on whether you write the unversioned form (default version) or the versioned form (e.g. `/learn/docs/v2/getting-started`). For inline version-specific content within a single page, use [`<If versions=…>`](/learn/docs/writing-content/components/if#by-version) or [`<Versions>`](/learn/docs/writing-content/components/versions).

<Tip title="Validating internal links">
The [`broken-links` rule](/learn/docs/configuration/site-level-settings#check-configuration) — run by [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check), including during `fern docs dev` — validates each internal link against the navigation tree built from your **local** YAML. It does not crawl your deployed site or follow external URLs. To check links on a published site, use the [Fern Dashboard](https://dashboard.buildwithfern.com/).
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 🐶
[Microsoft.Contractions] Use 'doesn't' instead of 'does not'.

## Catching missing redirects

You can use [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check) to automatically detect pages that were removed or moved without a redirect. Configure the [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration) in `docs.yml` to control its severity.
The [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration), run by [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check), compares the navigation tree built from your local YAML against the most recently **published** state of your site and flags previously-published URLs that no longer resolve and aren't covered by an entry in `redirects:`. Because it reads the published state, this rule (unlike other `fern check` rules) makes a network call and requires [`fern login`](/learn/cli-api-reference/cli-reference/commands#fern-login) or the `FERN_TOKEN` environment variable. It is skipped on first publish or when unauthenticated.
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.Hyphens] 'previously-published' doesn't need a hyphen.

## Catching missing redirects

You can use [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check) to automatically detect pages that were removed or moved without a redirect. Configure the [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration) in `docs.yml` to control its severity.
The [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration), run by [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check), compares the navigation tree built from your local YAML against the most recently **published** state of your site and flags previously-published URLs that no longer resolve and aren't covered by an entry in `redirects:`. Because it reads the published state, this rule (unlike other `fern check` rules) makes a network call and requires [`fern login`](/learn/cli-api-reference/cli-reference/commands#fern-login) or the `FERN_TOKEN` environment variable. It is skipped on first publish or when unauthenticated.
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 🐶
[Microsoft.Contractions] Use 'it's' instead of 'It is'.

## Catching missing redirects

You can use [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check) to automatically detect pages that were removed or moved without a redirect. Configure the [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration) in `docs.yml` to control its severity.
The [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration), run by [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check), warns you when a previously-published URL no longer resolves and isn't covered by an entry in your `redirects` entry. This catches pages you've moved or removed before they start returning 404s for existing inbound links.
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.Hyphens] 'previously-published' doesn't need a hyphen.

## Catching missing redirects

You can use [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check) to automatically detect pages that were removed or moved without a redirect. Configure the [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration) in `docs.yml` to control its severity.
The [`missing-redirects` rule](/learn/docs/configuration/site-level-settings#check-configuration), run by [`fern check`](/learn/cli-api-reference/cli-reference/commands#fern-check), compares the navigation tree built from your local YAML against the most recently **published** state of your site and flags previously-published URLs that no longer resolve and aren't covered by an entry in `redirects:`. This catches pages you've moved or removed before they start returning 404s for existing inbound links.
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.Hyphens] 'previously-published' doesn't need a hyphen.

@devalog devalog merged commit 069bd8f into main May 13, 2026
2 checks passed
@devalog devalog deleted the fern/docs-links-clarifications branch May 13, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant