Your anchor link works locally, then dies on GitHub

We ran the same anchors through nine markdown renderers to find out why.

Every anchor link has two halves

The link is plain markdown and works everywhere. The target is an element with a matching id, and that is the half that goes missing.

Headings get an id for free, mostly

GitHub slugs every heading. Stock markdown-it and marked do not, so without a plugin the target never exists.

Curly-brace ids are not markdown

Pandoc, kramdown and Python-Markdown honor them. GitHub prints the braces and folds them into the slug instead.

One empty HTML tag works everywhere

An empty anchor with an id, on its own line above the spot, passed through every renderer we tested that allows HTML.

GitHub renames your id

It adds a user-content prefix, then a page script maps your link back. Render the same HTML yourself and the link misses.

Linking into another file

Put the file path before the fragment. GitHub resolves it, static sites need a rewrite, and npm pages need a full URL.

Scrolls nowhere? Read the HTML

Search the rendered page for your id. Missing, prefixed, or encoded differently: that is your bug, not the link.

The portable rule

Lowercase id, empty anchor tag, blank line after it. Save curly braces for a parser you control.

Read the full guide