How to Fix Markdown Headings Inside Links

Swapping the heading and link elements can fix the invalid markdown.

March 5, 2026

Headings and links work fine separately:

## Heading

[Link](/page.html)
<h2>Heading</h2>

<p><a href="/page.html">Link</a></p>
https://example.com

Heading

Link

But if you put the heading inside the link, it breaks:

[## Heading](/page.html)
<p><a href="/page.html">## Heading</a></p>
https://example.com

The fix: Swap the order. Put the link inside the heading instead:

## [Heading](/page.html)
<h2><a href="/page.html">Heading</a></h2>
https://example.com

The same problem happens with other block elements like lists:

[### Product Features
- Feature 1
- Feature 2](/page.html)
<p>[### Product Features</p>
<ul>
  <li>Feature 1</li>
  <li>Feature 2](/page.html)</li>
</ul>
https://example.com

[### Product Features

  • Feature 1
  • Feature 2](/page.html)

Instead, keep them separate. Make each element clickable on its own.

### [Product Features](/page.html)

- [Feature 1](/page.html)
- [Feature 2](/page.html)
<h3><a href="/page.html">Product Features</a></h3>
<ul>
  <li><a href="/page.html">Feature 1</a></li>
  <li><a href="/page.html">Feature 2</a></li>
</ul>
https://example.com

Why this happens

Markdown has two types of elements: blocks and inlines.

Block elements: headings, paragraphs, lists, code blocks
Inline elements: links, emphasis, code spans, images

The rule is simple: blocks can contain inlines, but inlines cannot contain blocks.

When you try to nest a block inside an inline, markdown parsers ignore the block markup and treat it as plain text.

From the CommonMark specification:

We can think of a document as a sequence of blocks—structural elements like paragraphs, block quotations, lists, headings, rules, and code blocks. Some blocks (like block quotes and list items) contain other blocks; others (like headings and paragraphs) contain inline content—text, links, emphasized text, images, code spans, and so on.

Hope you learned something :)