Need AI Training/Help?CloudYeti.io/meet
MarkdownMe
Practical Markdown Guide

Markdown Heading Links and Anchors

A Markdown heading does not define one universal anchor format. Many renderers create an HTML id from the heading text, often by lowercasing it, replacing spaces with hyphens, and removing some punctuation. Link to the generated anchor with a fragment such as [Setup](#setup). Inspect the published HTML before relying on an ID.

How heading anchors are created

A heading such as ## Installation usually becomes an HTML heading with an id, for example <h2 id="installation">Installation</h2>. The exact conversion belongs to the renderer, not to Markdown syntax itself. Common transformations include lowercase text, spaces changed to hyphens, and punctuation removed. Repeated headings create a harder case. Some systems add a suffix to later duplicates, while others use a different identifier or reject the collision. Accented characters, symbols, apostrophes, and emoji also receive implementation-specific treatment. For dependable links, use short, distinct headings made from stable words. Avoid changing a heading after publishing if outside pages link to its fragment. A table of contents generator should read the final heading IDs rather than guessing them from source text.

Linking to a section

Use a fragment link when the renderer exposes a matching ID: [Installation](#installation). The fragment begins with a hash and remains part of the URL. For another page, include the path before the fragment, such as [Install guide](/docs/install#requirements). A link to a heading on the same page usually works after the document loads. A link to a dynamically generated page may fail if the application changes IDs between builds. Some GitHub pages show a link icon beside headings, which provides the platform's actual URL fragment. Copy that link when you need a platform-specific result. Do not place spaces in the fragment. URL encoding can matter for non-ASCII text, although the site may normalize it for you.

Stable IDs and portability

Markdown itself does not provide a portable attribute syntax for assigning an id to every heading. Some tools accept HTML, attributes, or custom directives, but those features are not interchangeable. An explicit HTML anchor such as <a id="api-limits"></a> may work in one publishing pipeline and be removed by another. If you control the renderer, configure its heading-ID rules and document them for authors. If you publish to several systems, test each output separately. Check heading hierarchy, duplicate IDs, keyboard focus, and whether a fragment scrolls to the intended section. Keep section names concise and avoid headings that differ only by punctuation. When renaming a heading, consider a redirect or compatibility anchor if existing links matter.

How do you do it step by step?

  1. 1Choose a concise heading with a distinct name and place it at the correct level in the document hierarchy.
  2. 2Render the page in the target platform and inspect the generated HTML or copy the heading link supplied by the platform.
  3. 3Create a Markdown link using the observed fragment, such as [Requirements](#requirements).
  4. 4Test the link from the same page and from a separate page, including the final published URL.
  5. 5Repeat the test after changing headings, enabling a new theme, or upgrading the Markdown processor.

Working example

This example uses a simple heading and a same-page fragment link.

Input
## Requirements

See the [requirements](#requirements) before you install the package.
Result
The renderer may produce an h2 element with id="requirements". Activating the link moves the browser to that heading.

The generated id is not guaranteed by Markdown. Confirm it in the published HTML, especially when headings contain punctuation, accents, or duplicate text.

Frequently asked questions

Does every Markdown heading get an anchor?
No. Many documentation systems add heading IDs, but a basic parser may output only an h1 through h6 element without an anchor.
How do I link to a heading?
Use a fragment link that matches the rendered heading ID, such as [API](#api). For another page, add the fragment after its path.
Why does my heading link work on one site but not another?
Different renderers normalize text differently and may handle duplicates, punctuation, or Unicode characters in separate ways.
Can I choose a custom heading ID?
Only if the target processor supports an attribute extension, HTML anchors, or another documented feature. Verify that the publishing pipeline preserves it.

Official references