Markdown Link Syntax: URLs, Relative Paths, Images, and Anchors

Markdown links look simple: put the visible text in square brackets and the destination in parentheses. Real documents quickly need more than the basic form, however. Links may point to websites, another file, a heading on the same page, or an image stored beside the document. This guide covers the useful forms and the mistakes that make otherwise valid links stop rendering.

The Basic Inline Link

The standard syntax is:

[Visible link text](https://example.com)

The result is a clickable phrase rather than a visible URL. You can add an optional title, which some browsers show as a tooltip:

[Project documentation](https://example.com/docs "Open the documentation")

Use descriptive link text. “Read the deployment guide” tells readers where a link goes; “click here” does not. Descriptive text also makes a page easier to scan with assistive technology.

Here is the quick Markdown link syntax reference:

Link type Markdown
Web page [Documentation](https://example.com/docs)
Another file [Setup](./setup.md)
Heading on this page [Troubleshooting](#troubleshooting)
Image ![Diagram](./diagram.png)
Visible URL <https://example.com>

The same bracket-and-parenthesis form works in .md files, README files, issue descriptions, and most CommonMark-based renderers. What changes between environments is how relative paths and generated heading anchors are resolved.

Linking to Another Markdown File

Documentation repositories commonly use relative paths:

[Installation guide](./guides/installation.md)
[Contributing](../CONTRIBUTING.md)

./ starts in the current file's directory. ../ moves up one directory. These links are portable while the repository structure remains intact, but they can break when a single Markdown file is copied into an online viewer without the surrounding files.

Use an absolute HTTPS URL when the destination should work independently of the repository:

[Published installation guide](https://docs.example.com/installation)

Linking to a Heading

An anchor link jumps to a section on the rendered page:

[Skip to troubleshooting](#troubleshooting)

## Troubleshooting

Renderers normally turn headings into lowercase IDs, replace spaces with hyphens, and remove some punctuation. Exact rules vary. A link such as #api-reference is usually safe for a heading named “API Reference,” but duplicate headings and punctuation-heavy titles deserve testing in the final renderer.

For a heading in another file, combine a path and fragment:

[Authentication errors](./api.md#authentication-errors)

Duplicate headings are a common source of broken anchors. A renderer may generate #examples for the first heading and #examples-1 for the second, but the suffix convention is not universal. Give important link targets unique heading text and verify the generated ID in the destination renderer.

Punctuation and Unicode also vary across platforms. A heading such as “What's New in v2.0?” may lose apostrophes and punctuation when converted to an ID. GitHub, documentation generators, and CommonMark-based viewers can produce different fragments from the same heading; avoid guessing when the link must work across all of them.

URLs With Spaces or Parentheses

A raw space can terminate a Markdown destination. For URLs containing spaces, encode them as %20 or enclose the destination in angle brackets:

[Release notes](<https://example.com/releases/Version 2.md>)

Balanced parentheses are accepted by CommonMark, but complicated URLs are easier to maintain when percent-encoded. If a link renders partly as plain text, inspect spaces and parentheses before changing the brackets.

Angle brackets are especially useful for a CommonMark link destination containing spaces:

[Design notes](<./Design Notes.md>)

They delimit the complete destination; they do not make a missing local file available after upload. For web URLs, percent-encoding spaces remains the more interoperable choice.

Reference-Style Links

Long destinations can make prose difficult to edit. Reference-style links move URLs out of the sentence:

Read the [API guide][api] and [security policy][security].

[api]: https://example.com/api
[security]: https://example.com/security "Security policy"

This is particularly useful when one destination appears several times. Reference labels are matched case-insensitively by CommonMark, but consistent lowercase labels are easier to maintain.

You can also use a compact form when the visible text and reference label match:

Read the [contributing guide].

[contributing guide]: https://example.com/contributing

Image Syntax

An image uses the same destination rules with an exclamation mark before the opening bracket:

![Architecture diagram](https://example.com/architecture.png)

Text inside the brackets becomes the image description and normally maps to HTML alt text. Describe the information conveyed by the image rather than writing “image” or repeating the filename.

A local image path is valid Markdown:

![Architecture diagram](./images/architecture.png)

It will only render when the viewer can also reach that file relative to the Markdown document. Uploading or sharing the .md file alone does not automatically include its image folder.

Email Addresses and Visible URLs

Angle brackets create explicit autolinks in CommonMark:

<https://example.com>
<team@example.com>

Some Markdown flavors automatically link bare URLs, but explicit syntax is more portable. Use a normal descriptive link for polished documentation and an autolink when displaying the destination itself is useful.

Links Without Visible Text

An empty label is technically parseable in some forms but produces an inaccessible or invisible link:

[](https://example.com)

Always provide meaningful link text. If the URL itself should be visible, use an autolink such as <https://example.com> rather than empty brackets.

A Link Debugging Checklist

When a Markdown link does not work:

  1. Confirm the closing bracket and parenthesis are present.
  2. Check the destination for an unencoded space.
  3. Verify whether the path is relative to the source file, repository, or rendered page.
  4. Test heading fragments in the final renderer.
  5. Make sure a local file or image was published with the Markdown.
  6. Test external links without relying on an authenticated browser session.

Paste the document into mdview.io to inspect the rendered links alongside the rest of the Markdown. Link syntax defines the destination, but the final location determines whether that destination can actually be reached.

For a deeper explanation of assets and repository paths, see how local Markdown files handle images and relative links. If only heading links fail after moving between platforms, use the cross-renderer heading-anchor guide.

Markdown Link FAQ

How do I link to a section in the same Markdown file?

Link to the heading's generated fragment, such as [Troubleshooting](#troubleshooting). Test punctuation, duplicate headings, and non-ASCII text in the final renderer.

How do I add a link to another file in a repository?

Use a relative destination such as [Setup](./docs/setup.md). The path is resolved from the current Markdown file and only works while the destination remains available at that location.

Why does a Markdown anchor work on GitHub but not elsewhere?

Heading-ID generation is platform behavior rather than core Markdown link syntax. Different renderers can normalize punctuation, Unicode, and duplicate headings differently.