ddonche/sheriff
0.18.0
1
0
docs reference
[[canonical-links]]

Canonical Links


A canonical link is the stable wikilink name for a page.

In Sheriff, every normal page can have a canonical field in frontmatter. That value is the page's official wiki identity. Most themes display the canonical link at the top of each page, along with a copy button. This is so you can simply paste that link into other content and it will work.

For example:

^^^^
title: House Andergard
author: Janden
layout: docs
meta_kind: docs
meta_type: entry
summary:
gloss:
canonical: house-andergard
aliases: [Andergard, Andergard House]
categories: [Houses, Royal Houses]
^^^^
^^^^
title: House Andergard
author: Janden
layout: docs
meta_kind: docs
meta_type: entry
summary:
gloss:
canonical: house-andergard
aliases: [Andergard, Andergard House]
categories: [Houses, Royal Houses]
^^^^

This means Sheriff treats the page as:

[[house-andergard]]
[[house-andergard]]

You can still write natural wikilinks such as:

[[House Andergard]]
[[House Andergard]]

Sheriff normalizes wikilinks before resolving them.


Why Is It Important?

Canonical links make wiki navigation stable.

They serve three primary purposes:

  • They give every page one official wikilink name.
  • They let navigation menus use wikilinks instead of hard-coded output URLs.
  • They prevent page-name conflicts from silently pointing to the wrong page.

Without canonical links, a page's wiki identity is derived from its filename. That works for simple sites, but it gets messy when a wiki grows, pages move, or two pages share the same filename in different folders.


Frontmatter

The recommended form is a plain slug:

canonical: house-andergard
canonical: house-andergard

Do not include the full wikilink syntax in frontmatter unless you have a specific reason.

Write this:

canonical: house-andergard
canonical: house-andergard

Not this:

canonical: [[house-andergard]]
canonical: [[house-andergard]]

The rendered copyable link still appears as:

[[house-andergard]]
[[house-andergard]]


Automatic Canonicals

If a page does not have a canonical field, Sheriff creates one during the build.

For example, this file:

content/wiki/houses/house_andergard.md
content/wiki/houses/house_andergard.md

gets this canonical value:

canonical: house-andergard
canonical: house-andergard

Sheriff writes that value back into the page's frontmatter.

After that, the canonical link belongs to the page until you change it yourself.


Moving Pages

Canonical links are stored in frontmatter so a page can move without changing its wiki identity.

For example, this page:

content/wiki/houses/house_andergard.md
content/wiki/houses/house_andergard.md

might later move to:

content/wiki/royalty/houses/house_andergard.md
content/wiki/royalty/houses/house_andergard.md

As long as the frontmatter still says:

canonical: house-andergard
canonical: house-andergard

then links to [[house-andergard]] still resolve to the page.


Name Conflicts

Sheriff does not allow two pages to claim the same canonical link.

For example, these two pages cannot both use:

canonical: tallahassee
canonical: tallahassee

If that happens, Sheriff stops the build and prints a readable Trailboss message showing both files.

You then choose which page keeps the canonical name and which page gets a more specific one.

For example:

canonical: tallahassee
canonical: tallahassee

and:

canonical: places-tallahassee
canonical: places-tallahassee

This keeps [[tallahassee]] from becoming ambiguous.


Generated Names

When Sheriff creates a canonical field for a new page, it starts with the filename.

For example:

content/wiki/characters/tallahassee.md
content/wiki/characters/tallahassee.md

becomes:

canonical: tallahassee
canonical: tallahassee

If another page would receive the same canonical name, Sheriff uses the parent folder to make the new one more specific.

For example:

content/wiki/places/tallahassee.md
content/wiki/places/tallahassee.md

can become:

canonical: places-tallahassee
canonical: places-tallahassee

You can edit the generated value if you want a different canonical link.


Aliases And Redirects

Use canonical for the page's official name.

Use aliases for old names, alternate names, spelling variants, and redirects.

For example:

^^^^
title: Focus Panels
author: Sheriff Docs
layout: docs
meta_kind: guide
meta_type: docs
summary:
gloss:
canonical: focus-panels
aliases: [Focus Panel, focus-panel]
^^^^
^^^^
title: Focus Panels
author: Sheriff Docs
layout: docs
meta_kind: guide
meta_type: docs
summary:
gloss:
canonical: focus-panels
aliases: [Focus Panel, focus-panel]
^^^^

This page's official wikilink is:

[[focus-panels]]
[[focus-panels]]

These older or alternate links also resolve to it:

[[Focus Panel]]
[[focus-panel]]
[[Focus Panel]]
[[focus-panel]]

Sheriff also generates redirect files for aliases when possible.


Navigation

Scout navigation can use canonical wikilinks.

In nav.yall, you can write:

menus:
  left_docs:
    Styling Guide:
      Images: [[Images]]
      Redirects: [[Redirects]]
      Canonical Links: [[Canonical Links]]
menus:
  left_docs:
    Styling Guide:
      Images: [[Images]]
      Redirects: [[Redirects]]
      Canonical Links: [[Canonical Links]]

Sheriff resolves those links through routes.json.

That means the menu does not need to know the final output path, such as:

docs/guides/canonical_links.html
docs/guides/canonical_links.html

The route data knows where the page renders.


Generated Pages

Generated admin pages also receive canonical route data.

If a generated page would conflict with a hand-written page, Sheriff gives the generated page a more specific canonical name.

For example, the hand-written Categories guide can keep:

canonical: categories
canonical: categories

while the generated category index can use:

canonical: categories-index
canonical: categories-index

The real authored page wins the clean name.


Routes JSON

Canonical links are stored in routes.json.

Each route includes the old filename-derived slug and the persistent canonical slug:

{
  "slug": "house-andergard",
  "canonical_slug": "house-andergard",
  "canonical": "[[house-andergard]]",
  "href": "/wiki/houses/house_andergard.html"
}
{
  "slug": "house-andergard",
  "canonical_slug": "house-andergard",
  "canonical": "[[house-andergard]]",
  "href": "/wiki/houses/house_andergard.html"
}

Trailboss and Scout use canonical_slug first, then fall back to slug for older route data.


Modules Involved

  • Routes JSON - stores canonical route data and writes missing canonical fields.
  • Trailboss - resolves wikilinks using canonical route data.
  • Scout - resolves navigation wikilinks using canonical route data.
  • Redirects - uses aliases for old names and alternate links.