Skip to content

feat: support disableAutolinkProtocols to opt out of GFM autolinks per protocol - #611

Open
sleitor wants to merge 1 commit into
vercel:mainfrom
sleitor:feat/disable-autolink-protocols
Open

feat: support disableAutolinkProtocols to opt out of GFM autolinks per protocol#611
sleitor wants to merge 1 commit into
vercel:mainfrom
sleitor:feat/disable-autolink-protocols

Conversation

@sleitor

@sleitor sleitor commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Closes #607.

What

Adds an optional disableAutolinkProtocols prop to <Streamdown> that disables GFM autolink-literal linking for specific URL protocols (e.g. mailto), as requested in #607.

<Streamdown disableAutolinkProtocols={["mailto"]}>
  {"Contact us at hello@example.com"}
</Streamdown>

Before:

<p>Contact us at <a href="mailto:hello@example.com">hello@example.com</a></p>

After (with disableAutolinkProtocols={["mailto"]}):

<p>Contact us at hello@example.com</p>
  • Protocol names are case-insensitive and accept an optional trailing colon ("mailto" and "mailto:" are equivalent).
  • Only literal autolinks created by remark-gfm's autolink-literal extension are affected (bare emails, bare http(s)/www URLs). Explicit markdown links ([text](mailto:...)) are left as links, since they're an intentional link, not an autolink.
  • Default behavior is completely unchanged when the prop is omitted — no extra plugin is added to the remark pipeline in that case.

How

mdast-util-gfm-autolink-literal doesn't tag the link nodes it creates, so a small remark plugin (packages/streamdown/lib/remark/disable-autolink-protocols.ts) identifies them structurally: a link with exactly one text child whose value reconstructs the node's url (accounting for the mailto: prefix GFM adds to bare emails). Matching nodes are unwrapped back to their text children. The plugin runs immediately after remark-gfm in the pipeline (before the CJK/math plugin slots), matching the existing "before/after gfm" plugin ordering convention.

It's exposed via the standard unified [plugin, options] tuple form rather than a plugin-factory closure — Streamdown's internal Markdown processor cache keys processors by plugin name + JSON.stringify(options), and a factory returning a fresh anonymous closure per call would always serialize to the same cache key, causing different disableAutolinkProtocols configurations to silently reuse a stale cached processor (caught this via a failing test while developing).

Testing

Added packages/streamdown/__tests__/disable-autolink-protocols.test.tsx covering:

  • bare email not linked when mailto is disabled
  • default behavior (prop omitted) unchanged
  • explicit [text](mailto:...) links stay linked
  • http/https autolinks still linked when only mailto is disabled
  • case-insensitivity and the "mailto:" form
  • disabling https leaves mailto autolinks untouched
  • end-to-end wiring through the <Streamdown disableAutolinkProtocols> prop itself

pnpm -F streamdown exec vitest run passes except for 5 pre-existing failures on main unrelated to this change (image-placeholder / incomplete-image-sanitize tests, verified failing identically on a clean upstream/main checkout before my changes).

Also updated apps/website/content/docs/configuration.mdx with the new prop, and added a changeset.

…r protocol

Adds an optional disableAutolinkProtocols prop to <Streamdown> that lets
consumers turn off GFM autolink-literal linking for specific URL protocols
(e.g. mailto). Implemented as a remark plugin that runs after remark-gfm,
identifying autolink-literal link nodes structurally (single text child
reconstructing the URL) and unwrapping them to plain text when their
protocol is disabled. Explicit markdown links ([text](url)) are left alone.

Protocol names are case-insensitive and accept an optional trailing colon.
The pipeline is unchanged when the prop is omitted.

Closes vercel#607
@vercel

vercel Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

@sleitor is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Support disabling autolinks for specified URL protocols

1 participant