Tutorials 15 min read

target=\"_blank\" Links Don't Exist in Standard Markdown — Here's the HTML That Works and What Each Renderer Does With It

MMNMNOTE
markdownhtmllinksgithubkramdownrehypeweb-development

Standard Markdown has no syntax for opening links in a new tab. Raw HTML is the only portable route — but GitHub silently strips the target attribute and rewrites your rel. This reference covers the solution, the security hygiene, and what every major renderer actually does.


The question appears on Stack Overflow more than any other Markdown formatting question on its axis: "Can I create links with target="_blank" in Markdown?" has accumulated 557,175 views since 2010.1 A related thread — "Markdown open a new window link" — adds another 171,321.2 Combined, that is well over 700,000 documented attempts to find an answer.

There is a reason so many people ask: the answer is not intuitive, and the standard is firm.


The short answer

Standard Markdown — CommonMark, the spec that governs GitHub READMEs, most static-site generators, and virtually every Markdown library — provides no syntax for link attributes. The CommonMark specification defines a link as containing "link text (the visible text), a link destination (the URI that is the link destination), and optionally a link title."3 There is no attribute slot. Raw <a> HTML is the only portable route. GitHub, however, strips the target attribute entirely when it renders Markdown, and replaces whatever rel you wrote with rel="nofollow". On GitHub, new-tab behaviour is simply not available.

Before reaching for the workaround, it is worth noting what the research says. A 2010 study by Dubroy and Balakrishnan (CHI '10) followed 21 participants and found that all of them had multiple tabs open during most of their browsing sessions — and "most of our participants switched tabs more often than they used the back button."4 New tabs genuinely reflect how most people browse.

That said, the WCAG 2.2 accessibility guidelines advise restraint. Failure F22 notes that "new windows take the focus away from what the user is reading or doing,"5 and Understanding SC 3.2.5 adds that opening new windows "can be disorienting for people … unless the user has requested this."6 The recommended technique (H83) is to allow opening in a new window only when the user has explicitly requested it.7

Nielsen Norman Group has held this position since 1999, advising that for most links, the same tab or window is the right default — with exceptions for PDFs and similar large-file downloads.8

The upshot: use target="_blank" deliberately — external resources the user will want to reference while continuing to read, or file downloads — not reflexively. When you do use it, signal the behaviour in the link text or with an icon so the user is not surprised.

Why Markdown has no attribute syntax

John Gruber's original design philosophy was explicit: "HTML is a publishing format; Markdown is a writing format."9 The CommonMark spec follows that division cleanly. Its §6.3 defines links in terms of text, destination, and title — full stop.3 There is no {attr=value} slot on a standard link. When you write [text](url), that is everything the syntax offers.

A few non-standard extensions add attribute support — kramdown's inline attribute list (IAL) syntax and pandoc's link_attributes extension are the two most prominent — but neither is CommonMark-compatible, and both fail silently on renderers that do not understand them.

The raw HTML route

For renderers that allow passthrough HTML, the solution is to write the <a> tag directly:

<a href="https://example.com" target="_blank" rel="noopener noreferrer">Link text</a>

This is the portable answer wherever the renderer does not sanitise HTML. It survives commonmark.js, micromark, pandoc (HTML output mode), and markdown-it with html: true. It does not survive GitHub README rendering.

Does rel="noopener noreferrer" still matter?

The short answer is: yes, as defence-in-depth — but the original threat has been substantially mitigated by browsers.

The historical concern was that a page opened via target="_blank" could access the opener's window object through window.opener, enabling tab-napping attacks. Mathias Bynens documented this with a live demo: "malicious.html has full control over this document's window object!"10

The WHATWG addressed this in HTML PR #4330, merged 2019-02-07: the spec now mandates that _blank automatically sets the noopenerFlag.11 Browsers shipped this behaviour at different points — Safari 12.1 (2019-03-25), Firefox 79 (2020-07-28), Chrome 88 (2021-01-19).12 MDN confirms the result: "Setting target=\"_blank\" on <a> elements implicitly provides the same rel behavior as setting rel=\"noopener\" which does not set window.opener."13

For modern browsers, the window.opener vector is closed by the browser itself.

Two reasons remain to include rel="noopener noreferrer" explicitly:

  1. Defence-in-depth for older browsers. Browsers shipped implicit noopener between 2019 and 2021. Any user on an older build — embedded webviews, enterprise-locked browsers, long-term support distributions — may not have it. The scale of the exposed surface is documented: the Dirty Clicks study (WWW 2020) measured 239,628 _blank links across more than 850,000 domains and found that roughly 1,324 domains (about 2%) included any protection.14 The explicit attribute costs nothing and covers the tail.

  2. noreferrer does a separate job. The MDN documentation for rel="noreferrer" states: "The noreferrer keyword may be used with a, area, and form elements. This keyword does not affect processing of the link in any way … but causes the browser to omit the Referer header when following the link, and sets noopener."15 This is independent of the implicit-flag behaviour. MDN's Referrer-Policy reference notes that the browser's default referrer policy has been strict-origin-when-cross-origin since November 2020 (before that it was no-referrer-when-downgrade).16 For cross-origin links where referrer information still leaks under the current default policy, noreferrer is the explicit control.

The concise guidance: frame rel="noopener noreferrer" as a good-practice default that handles older browsers and referrer privacy together, not as a mandatory requirement for modern browsers.

Renderer matrix

This table covers the most common rendering environments. The GitHub result is from a direct measurement against the GitHub POST /markdown API (both gfm and markdown modes, 12 test cases).17 The parser and sanitizer results come from a measurement run across 14 parser settings and 3 sanitizers.18

Renderer / environmenttarget="_blank" preserved?rel written by tool?Notes
GitHub README (POST /markdown, gfm)NO (0 of 12)Writes rel="nofollow"Strips author's rel too; both gfm and markdown modes identical
GitHub README (POST /markdown, markdown)NO (0 of 12)Writes rel="nofollow"Same result as gfm
commonmark.js (strict)YESNoRaw HTML passthrough; no sanitizer layer
micromark (CommonMark strict)YESNoPassthrough
markdown-it (html: true)YESNoOnly with html option enabled
markdown-it (html: false, default)NO—Strips all raw HTML by default
pandoc → HTML outputYESNo (unless Lua filter)Raw HTML passthrough
pandoc → native Markdown round-tripDropped—target has no place in pandoc's AST
sanitize-html (defaults)YESDoes NOT add noopenerAllows href, name, target; rel is not in the default allowlist
rehype-external-links (configured)YESAdds noopener noreferrerRecommended config adds rel automatically
kramdown (Jekyll)YES via IALNo{:target="_blank"} syntax; non-standard to CommonMark

The sanitize-html gotcha. The default allowlist for sanitize-html includes target as an allowed attribute on <a> — but rel is not in that default list.19 This means a sanitize-html setup running at default configuration will pass target="_blank" through to the browser while silently stripping any rel="noopener noreferrer" you wrote. The sanitizer's presence can create a false sense of security: the author adds the security attribute, the sanitizer removes it, and the browser sees an unprotected _blank link on older browser versions. If you use sanitize-html with external links, add rel to the allowed attributes explicitly.

Platform-specific paths

GitHub README and GitHub POST /markdown

GitHub does not support target="_blank" in README files or any Markdown processed through its POST /markdown API. As measured, target is stripped in every case and the author's rel is replaced with rel="nofollow". There is no workaround available within GitHub README Markdown.

GitHub Pages with a Jekyll/kramdown pipeline is a different rendering path from the GitHub README API — but the behaviour of safe_mode settings in that environment has not been independently verified here. Keep the two paths distinct.

kramdown (Jekyll, GitHub Pages)

kramdown supports inline attribute lists (IALs) placed directly after a link. The kramdown documentation confirms: "Additional link attributes can be added by using a span IAL after the inline link."20 In practice this looks like:

[Link text](https://example.com){:target="_blank" rel="noopener noreferrer"}

This syntax works in Jekyll-based sites. It does not work in GitHub README rendering, which uses CommonMark strict, not kramdown.

markdown-it

markdown-it has no built-in target support. With html: true, raw <a target="_blank"> passes through. The markdown-it architecture documentation illustrates the ability to inject HTML attributes to links via a core rule.21 For systematic new-tab links across a site, markdown-it-link-attributes is the common plugin choice.

For projects using the unified/rehype ecosystem, rehype-external-links is the idiomatic solution. Its README describes the behaviour: "Adds rel attributes to external links. … When using target, add rel=\"noopener\" and rel=\"noreferrer\". … When not using target, add rel=\"nofollow\" to external links."22 Configured with a target: '_blank' option, it handles both the target attribute and the rel hygiene automatically.


FAQ

How do I open a Markdown link in a new tab? Standard Markdown has no native syntax for this. Use raw HTML: <a href="https://example.com" target="_blank" rel="noopener noreferrer">link text</a>. This works wherever the renderer allows passthrough HTML. GitHub README does not — it strips target entirely.

Does GitHub strip target="_blank" from Markdown? Yes. GitHub's POST /markdown API strips target in every case — both gfm and markdown rendering modes — and replaces whatever rel the author wrote with rel="nofollow". New-tab links are not supported in GitHub READMEs.

Is rel="noopener noreferrer" still required in 2026? Not strictly required by modern browsers — the WHATWG HTML spec (PR #4330, merged 2019-02-07) made target="_blank" imply noopener, and all major browsers shipped this by 2021 (Safari 12.1, Firefox 79, Chrome 88). It remains recommended as defence-in-depth for older browsers, and noreferrer independently controls Referer header omission regardless of browser version.

How do I open links in a new tab with kramdown? Use an inline attribute list (IAL) after the link: [text](url){:target="_blank" rel="noopener noreferrer"}. This works in Jekyll-based sites with kramdown. It does not work in GitHub README rendering, which uses CommonMark strict.

How do I open links in a new tab with markdown-it? Enable html: true in your markdown-it configuration to allow raw <a target> passthrough, or add a core rule or the markdown-it-link-attributes plugin for systematic new-tab behaviour. The default configuration (html: false) strips all raw HTML.

Does sanitize-html allow target="_blank"? The default allowlist in sanitize-html includes target as a permitted attribute on <a> — but it does not include rel. A default-configured sanitize-html will pass target="_blank" through while stripping rel="noopener noreferrer". Add rel to the allowed-attributes list explicitly.

What is the WCAG position on opening links in new tabs? WCAG 2.2 advises against opening new windows without the user's request. Failure F22 flags it as a failure of Success Criterion 3.2.2; Technique H83 permits new-tab links only when the user has requested them. When using target="_blank", indicate the behaviour in the link text or with an icon so the user is not surprised.


Closing

The limitation is by design: Markdown's writing-format constraint is what makes it portable. When new-tab behaviour matters, the choice is between raw HTML (which works everywhere except GitHub README), a renderer-specific extension (kramdown IAL, rehype-external-links, a markdown-it plugin), or accepting that some environments will never support it. Knowing which category your renderer falls into is the whole problem — and now you have the matrix.


If you keep your notes in plain Markdown, the question of which renderer interprets them is always close by. mnmnote.com is a local-first Markdown editor where your files stay on your device, readable by any tool that understands plain text.


References


Footnotes

  1. Stack Overflow Q4425198 "Can I create links with 'target="_blank"' in Markdown?": score 847, 557,175 views, asked 2010-12-13. Stack Overflow / Stack Exchange API v2.3 (accessed 2026-11-04). https://api.stackexchange.com/2.3/questions/4425198?site=stackoverflow ↩

  2. Stack Overflow Q3492153 "Markdown open a new window link": score 191, 171,321 views, asked 2010-08-16. Stack Overflow / Stack Exchange API v2.3 (accessed 2026-11-04). https://api.stackexchange.com/2.3/questions/3492153?site=stackoverflow ↩

  3. CommonMark Spec 0.31.2, §6.3 Links. https://spec.commonmark.org/0.31.2/ (accessed 2026-11-04). ↩ ↩2

  4. Dubroy, P. & Balakrishnan, R. "A Study of Tabbed Browsing Among Mozilla Firefox Users." CHI 2010, ACM. https://dgp.toronto.edu/~ravin/papers/chi2010_tabbedbrowsing.pdf (accessed 2026-11-04). N=21. ↩

  5. W3C WAI. WCAG 2.2 Failure F22 "Failure of Success Criterion 3.2.2 due to opening windows that are not requested by the user." https://www.w3.org/WAI/WCAG22/Techniques/failures/F22 (accessed 2026-11-04). ↩

  6. W3C WAI. WCAG 2.2 Understanding SC 3.2.5 "Change on Request." https://www.w3.org/WAI/WCAG22/Understanding/change-on-request.html (accessed 2026-11-04). ↩

  7. W3C WAI. WCAG 2.2 Technique H83 "Using the target attribute to open a new window on user request." https://www.w3.org/WAI/WCAG22/Techniques/html/H83 (accessed 2026-11-04). ↩

  8. Nielsen, J. & Kaley, A. "Opening Links in New Browser Windows and Tabs." Nielsen Norman Group, 2020-02-02. https://www.nngroup.com/articles/new-browser-windows-and-tabs/ (accessed 2026-11-04). ↩

  9. Gruber, J. "Markdown: Syntax." Daring Fireball (2004). https://daringfireball.net/projects/markdown/syntax (accessed 2026-11-04). ↩

  10. Bynens, M. rel=noopener demo page. https://mathiasbynens.github.io/rel-noopener/ (accessed 2026-11-04). ↩

  11. WHATWG HTML PR #4330 "Make target=_blank imply noopener; support opener." Merged 2019-02-07. https://github.com/whatwg/html/pull/4330 (accessed 2026-11-04). ↩

  12. @mdn/browser-compat-data. implicit_noopener: Chrome 88 (2021-01-19); Firefox 79 (2020-07-28); Safari 12.1 (2019-03-25). https://raw.githubusercontent.com/mdn/browser-compat-data/69c382b1903d/html/elements/a.json (SHA-pinned, accessed 2026-11-04). ↩

  13. MDN Web Docs. <a>: The Anchor element. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a (accessed 2026-11-04). ↩

  14. Villar-Liñán et al. "Dirty Clicks." WWW 2020. DOI 10.1145/3366423.3380124. OA copy: https://deustoteka.deusto.es (accessed 2026-11-04). ↩

  15. MDN Web Docs. rel=noreferrer. https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/noreferrer (accessed 2026-11-04). ↩

  16. MDN Web Docs. Referrer-Policy. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy (accessed 2026-11-04). ↩

  17. Own measurement. GitHub POST /markdown — target attribute kept in 0 of 12 cases (both gfm and markdown modes); author's rel replaced by rel="nofollow" in every case. Receipt: /tmp/547rc/gh-out.json sha256 a46038ea… (2026-11-04). ↩

  18. Own measurement. 14 parser settings + 3 sanitizers tested — raw <a target> kept in 11/14 parser settings; {target=} kept in 4/14; {:target=} kept in 3/14; sanitizers gave 3 different answers. Receipt: /tmp/547rc/local-out.json sha256 6faeabcf… (2026-11-04). ↩

  19. apostrophecms/sanitize-html (default allowlist). target permitted on a; rel not in default allowlist. https://github.com/apostrophecms/sanitize-html#readme (accessed 2026-11-04). ↩

  20. kramdown documentation, Syntax — Links section. https://kramdown.gettalong.org/syntax.html (accessed 2026-11-04). ↩

  21. markdown-it contributors. docs/architecture.md. https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md (accessed 2026-11-04). ↩

  22. Wormer, T. rehype-external-links README @b0ada86. https://github.com/rehypejs/rehype-external-links (accessed 2026-11-04). ↩