Links are where Markdown most often breaks after a document leaves the machine that wrote it. The syntax is small — four characters and a path — but the path is resolved by whatever renders the file, and that renderer is rarely the one the author used. A design doc that reads perfectly in an editor can arrive with dead cross-references, a table of contents that jumps nowhere, and images that resolve to broken icons.
This is a reference for every link form in Markdown, what each one resolves against, and which ones survive being shared.
| Need | Syntax |
|---|---|
| Web URL | [label](https://example.com) |
| Relative file | [spec](./docs/spec.md) |
| Heading anchor | [jump](#section-heading) |
| Image |  |
| Image as a link | [](https://example.com) |
Parentheses inside a URL, brackets inside link text, and the
markdown-escapenpm package are covered separately in how to escape parentheses and brackets in Markdown.
The basic form is link text in square brackets followed by the destination in parentheses.
[mdview.io](https://mdview.io)
[the architecture doc](./docs/architecture.md)
A third element, a quoted title, becomes the tooltip on hover:
[mdview.io](https://mdview.io "Render Markdown and Mermaid")
The destination can be an absolute URL, a path relative to the current file, or an anchor pointing inside the document. Those three cases behave very differently once the file moves.
The last branch is the one that catches people. A relative path is only meaningful while the linked file sits in the same directory structure, on the same host, as the file pointing at it.
Relative paths resolve against the location of the file containing the link, not against the project root.
| Goal | Syntax | Resolves to |
|---|---|---|
| Same directory | [spec](./spec.md) |
spec.md beside the current file |
| Same directory, terse | [spec](spec.md) |
identical to the above |
| Subdirectory | [spec](./api/spec.md) |
api/spec.md below the current file |
| Parent directory | [readme](../README.md) |
one level up |
| Two levels up | [root](../../README.md) |
two levels up |
| From the repository root | [spec](/docs/spec.md) |
the host's root, not the repo root |
That final row is the common mistake. A leading slash means the root of the web server, so a link written as /docs/spec.md works on GitHub — where the repository happens to sit near the root — and breaks almost everywhere else. Prefer ./ and ../ forms for links that need to travel.
An anchor link points at a heading inside a document using a hash and a slug of the heading text.
[Jump to deployment](#deployment-notes)
Most renderers generate the slug by lowercasing the heading, dropping punctuation, and replacing spaces with hyphens. A heading reading ## Deployment Notes becomes #deployment-notes.
To link to a heading in a different file, combine the two forms — the relative path first, then the anchor:
[see the rollback section](./runbook.md#rollback)
Anchor generation is the least portable part of Markdown, because it is not specified by CommonMark at all. Each renderer invents its own rule, which is why a table of contents can work in one place and fail in another. Markdown heading links across GitHub and CommonMark renderers covers those differences in detail.
| Heading | Common slug | Notes |
|---|---|---|
## Deployment Notes |
#deployment-notes |
Consistent nearly everywhere |
## Step 1. Install |
#step-1-install |
The period is dropped, not hyphenated |
## What's New? |
#whats-new |
Apostrophe and question mark removed |
## API (v2) |
#api-v2 |
Parentheses removed, inner space becomes a hyphen |
## Deploy twice |
#deploy, #deploy-1 |
Duplicates get a numeric suffix in document order |
## 部署说明 |
varies | Non-ASCII headings differ sharply between renderers |
When an anchor has to be stable, the safest approach is to keep headings short, ASCII, and unique within the file.
Reference links move the destination out of the sentence and define it elsewhere, which keeps dense prose readable and lets one URL serve several mentions.
The [specification][spec] supersedes the [old draft][spec-v1].
[spec]: https://example.com/spec-v2
[spec-v1]: https://example.com/spec-v1
The label is case-insensitive, and the definitions can sit anywhere in the file — conventionally at the bottom. If the label and the link text are identical, the second pair of brackets can be left empty:
Read the [changelog][] before upgrading.
[changelog]: https://mdview.io/changelog
CommonMark supports autolinks: a bare URL or email address wrapped in angle brackets becomes a link with itself as the text.
<https://mdview.io>
<team@example.com>
The angle brackets matter. A bare URL with no brackets is only linkified by renderers that implement GitHub Flavored Markdown's extended autolink behaviour; under strict CommonMark it stays plain text. Wrapping it removes the ambiguity.
A space inside a destination ends the destination early and breaks the link. Two fixes work:
[quarterly report](<./Q3 report.pdf>)
[quarterly report](./Q3%20report.pdf)
Angle brackets around the destination let it contain spaces. Percent-encoding replaces the space with %20. Closing parentheses inside a URL — common in encyclopaedia links — need a backslash escape or angle brackets, or the renderer will end the link at the first one it meets.
An image is a link with a leading exclamation mark. The bracketed text becomes the alt text rather than the visible label.

Images follow exactly the same resolution rules as links, which is why a document full of local screenshots renders cleanly on the author's disk and arrives at a reviewer with every image missing. To make an image travel, either host it and use an absolute URL, or embed it directly as a base64 data URI.
Wrapping an image in a link makes it clickable:
[](https://ci.example.com/builds)
Links work normally inside table cells and list items, with one caveat: a pipe character inside a link destination will be read as a column separator and split the row. Percent-encode it as %7C when it appears in a URL inside a table.
| Service | Runbook |
|---|---|
| Ingest | [runbook](./runbooks/ingest.md) |
| Billing | [runbook](./runbooks/billing.md#escalation) |
Most broken links are not syntax errors. They are correct paths resolved against the wrong base.
../ in it./Users/you/screenshots/api.png cannot resolve for anyone else.AI-generated documentation concentrates all five failures. A model asked to produce a design doc will confidently emit a table of contents with anchors it never verified and cross-references to files that were never created.
http, ./, ../, or #? A leading / is usually a mistake.Use a hash followed by the slugged heading text, as in [jump](#deployment-notes) for a heading reading ## Deployment Notes. Lowercase it, remove punctuation, and replace spaces with hyphens.
Combine the relative path and the anchor: [rollback](./runbook.md#rollback). Both halves must be correct — the path relative to the current file, and the slug relative to the target file's headings.
Use a relative path such as ./docs/spec.md or ../README.md. Avoid a leading slash, which resolves against the web server root rather than the repository root.
Anchor slugging is not part of the CommonMark specification, so each renderer implements its own rule for punctuation, duplicates, and non-ASCII characters. A link tuned to one renderer's rule can fail in another.
Markdown has no syntax for it. Renderers that permit inline HTML accept an anchor tag with a target attribute; renderers that sanitise HTML will strip it.
They render identically. Inline links keep the URL in the sentence; reference links move it to a labelled definition elsewhere in the file, which suits prose with many citations or one URL repeated several times.
Every failure above is invisible in a text editor, because a raw .md file shows the syntax rather than the result. They become obvious the moment the document is rendered.
mdview.io renders Markdown the way a reader will receive it — resolved links, generated heading anchors, images, GFM tables, LaTeX math through KaTeX, and Mermaid diagrams with zoom, pan, and SVG or PNG export. Open a file, publish it to a share link, and follow the cross-references yourself before the document reaches the people who depend on them.