Skip to content

feat: add GitHub-style admonition (GFM Alerts) support#467

Open
ayhansipahi wants to merge 10 commits intovercel:mainfrom
ayhansipahi:feat/admonition-support
Open

feat: add GitHub-style admonition (GFM Alerts) support#467
ayhansipahi wants to merge 10 commits intovercel:mainfrom
ayhansipahi:feat/admonition-support

Conversation

@ayhansipahi
Copy link
Contributor

@ayhansipahi ayhansipahi commented Mar 16, 2026

Summary

  • Add built-in support for GitHub-style admonition blocks (> [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING], > [!CAUTION])
  • Remark plugin transforms blockquotes with [!TYPE] markers into styled callout boxes with type-specific icons and colors
  • Fully customizable via components, icons, and translations props
  • Add admonitions documentation page and update existing docs (components, internationalization, GFM)
  • Add admonition examples to the playground

New files

  • packages/streamdown/lib/remark/admonition.ts — Remark plugin (AST-level transformation)
  • packages/streamdown/lib/admonition.tsx — Memoized React component with 5 color themes
  • packages/streamdown/__tests__/admonition.test.tsx — 13 tests covering plugin + component features
  • apps/website/content/docs/admonitions.mdx — Documentation page

Modified files

  • packages/streamdown/lib/icons.tsx — 5 new SVG icon components
  • packages/streamdown/lib/icon-context.tsx — Extended IconMap interface
  • packages/streamdown/lib/translations-context.tsx — 5 new i18n keys
  • packages/streamdown/lib/components.tsx — Register admonition component
  • packages/streamdown/index.tsx — Add to default remark plugins + sanitize schema + export
  • apps/website/content/docs/components.mdx — Add admonition to available components list
  • apps/website/content/docs/internationalization.mdx — Add admonition translation keys
  • apps/website/content/docs/gfm.mdx — Cross-link to admonitions page
  • apps/website/app/[lang]/playground/components/playground-editor.tsx — Add admonition examples

Test plan

  • All 995 tests pass (74 test files)
  • Linter clean (ultracite check)
  • Type check passes (pnpm check-types)
  • Changeset included (minor bump)
image image

Add a remark plugin that transforms GitHub-flavored blockquote admonitions
(NOTE, TIP, IMPORTANT, WARNING, CAUTION) into styled admonition components.
Includes remark plugin, minimal React component, sanitization config,
component registration, and comprehensive tests.
…ntegration

Add 5 SVG icon components (Note, Tip, Important, Warning, Caution) and
register them in IconMap. Add translation strings for admonition titles.
Update the admonition component to use useIcons() and useTranslations()
hooks instead of hardcoded title text. Add tests for icon rendering,
custom translations, and component override support.
Title text and icon rendering tests now verify all 5 admonition types
instead of only testing NOTE.
Extract detectAdmonitionType and stripMarker helper functions to bring
cognitive complexity below the linter threshold. Also apply formatter
fixes to test file.
Add all 5 admonition types (NOTE, TIP, IMPORTANT, WARNING, CAUTION) to
the playground's default markdown showcase.
@vercel
Copy link
Contributor

vercel bot commented Mar 16, 2026

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

A member of the Team first needs to authorize it.

@ayhansipahi ayhansipahi force-pushed the feat/admonition-support branch from 9de5cc9 to 60031a6 Compare March 16, 2026 08:13
@haydenbleasel
Copy link
Contributor

Awesome thanks @ayhansipahi - im surprised this isn't included in GFM! I was reading remarkjs/remark-gfm#62 and found there's some existing rehype plugins we could use instead of rolling our own e.g. https://github.com/chrisweb/rehype-github-alerts

@ayhansipahi
Copy link
Contributor Author

https://github.com/chrisweb/rehype-github-alerts

Thanks for the catch, @haydenbleasel. I didn't notice this plugin. I'll update the PR.

@ayhansipahi
Copy link
Contributor Author

Thanks for the catch, @haydenbleasel. I didn't notice this plugin. I'll update the PR.

Actually, after looking into rehype-github-alerts more closely, I think our custom remark plugin is the better fit here. Here's why:

  1. Layer mismatchrehype-github-alerts operates at the rehype (HAST) level, outputting raw HTML divs with CSS classes like markdown-alert-note. Streamdown works at the remark (MDAST) level, mapping blockquotes to custom React components via hName/hProperties — which gives us direct integration with our component system (icons, theming, dark mode, translations).

  2. More code, not less — To use rehype-github-alerts with our React component architecture, we'd need a custom build function that essentially reimplements what our current ~85-line remark plugin already does cleanly.

  3. Streaming support — Our plugin handles empty body / partial content scenarios for streaming, which rehype-github-alerts doesn't account for.

Agreed it's surprising this isn't in GFM though — that discussion thread has been open for a while!

@haydenbleasel
Copy link
Contributor

ok that makes sense. in that case i feel like we should potentially create a new package called remark-gfm-admonition which we can publish separately so others can use it, import that into Streamdown alongside the other remark plugins and leave Remend to handle it's core focus (markdown healing).

@ayhansipahi
Copy link
Contributor Author

Good call! The monorepo already has a clear pattern with streamdown-code, streamdown-math, streamdown-mermaid etc. I'll create packages/remark-gfm-admonition as a standalone package, extract the remark plugin there, and have Streamdown import it as a dependency. That way it's independently publishable and Remend stays focused on markdown healing.

@ayhansipahi ayhansipahi force-pushed the feat/admonition-support branch from 0de21ff to 1c70a02 Compare March 17, 2026 00:17
Create a new `remark-gfm-admonition` package that parses GitHub-flavored
admonition blockquotes ([!NOTE], [!TIP], etc.) and produces GitHub-compatible
HTML output. Streamdown now consumes this package via a thin post-processor
that maps the output to its React component system.
@ayhansipahi ayhansipahi force-pushed the feat/admonition-support branch from 1c70a02 to b54e355 Compare March 17, 2026 19:49
"unified": "^11.0.5",
"vitest": "^4.0.15"
},
"author": "Hayden Bleasel <hayden.bleasel@vercel.com>",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's entirely up to you whether or not to give me credit. I don't mind either way.

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.

2 participants