Skip to content

markdown-to-jsx@9.10.0

Choose a tag to compare

@github-actions github-actions released this 31 Jul 04:39
· 11 commits to main since this release
8f1435d

Minor Changes

  • 02bae9f: Heading ids are generated from each heading's plain text content instead of its raw markdown source. Link destinations, formatting markers, and image alt text no longer leak into the id (for example ## [text](https://e.com) becomes id="text" rather than id="texthttpsecom"). Anchors on headings that contained links, images, or autolinks may change; plain-text headings are unaffected. Duplicate-id suffixes (foo, foo-1) still apply.
  • 02bae9f: Rejected image destinations now use null on the parsed AST the same way rejected links already do, so TypeScript consumers can treat ImageNode.target and LinkNode.target as string | null. Compilers still omit src for rejected images and the markdown compiler still re-emits them as ![alt]().
  • 4d08fd8: Headings that share the same text now get unique HTML ids automatically (introduction, introduction-1, introduction-2), matching the usual Markdown hosting behavior. A custom slugify still controls the base string; uniqueness is applied afterward, so you no longer need a stateful slugify closure that breaks under React Strict Mode.

Patch Changes

  • 02bae9f: Link and image destinations that hide a dangerous scheme behind HTML entities (for example [x](javascript:alert(1))) are now rejected the same way as a literal javascript: URL. Compilers drop the href for rejected links and omit the src for rejected images. The markdown compiler re-emits a rejected image as ![alt]() rather than ![alt](null). Direct AST rendering also re-checks link targets before they become hrefs.

  • 02bae9f: Single-line <script>, <style>, <pre>, and <textarea> blocks keep their text content when tagfilter is off, including under forceInline. Previously the React output could emit an empty tag and drop the body.

  • 4d08fd8: Custom JSX components written in PascalCase, and hyphenated custom elements, keep their markdown children when a blank line appears between the opening and closing tags. Content after the blank no longer leaks out as a sibling of the component.

  • e9a253d: Ship an llms.txt cheatsheet with the package and at markdown-to-jsx.quantizor.dev/llms.txt, so coding assistants can pick up the entry points, options, recipes, and AST shapes in a single short read instead of the full README.

    The cheatsheet leads with the questions people actually ask: why a single newline is not a line break, how to wire up a syntax highlighter or KaTeX, opening links in a new tab, restricting which tags render, and the traps around indented template literals and case-sensitive override keys.

    Two documentation corrections come along with it. The HTML entry point example named an export that does not exist; the helper there is astToHTML. And the class added to a fenced code block is language-<lang>, with the older lang-<lang> alongside it on the JSX renderers, rather than lang-<lang> alone as previously written.

  • 02bae9f: The markdown compiler now re-emits processing instructions (<?xml ?>), CDATA sections, declarations (<!DOCTYPE html>), and orphan closing tags exactly as written. Previously these were reconstructed as a generic self-closing element, which mangled a processing instruction like <?xml version="1.0"?> down to <? /> and dropped CDATA and declaration content entirely.

  • 02bae9f: optimizeForStreaming now defers incomplete HTML the same way in every compiler, including Solid and Vue. Tag-like prefixes that have not finished arriving (Hello <Citation, <!--…) stay hidden until they complete, while ordinary less-than text (5 < 3) keeps rendering.

  • 02bae9f: Dangerous url(javascript:…) (and similar) payloads in raw HTML style attributes are now stripped from the HTML and Markdown string outputs, matching the React-family compilers.

  • 02bae9f: Table cells that contain a backslash before a pipe are escaped correctly when compiling back to Markdown, so the pipe no longer splits the row on re-parse.

  • 02bae9f: Dangerous HTML tags (<script>, <iframe>, <style>, and similar) are escaped by default across the React, HTML, Solid, Vue, and React Native outputs. Matching GFM, only each tag's leading < is neutralized; the body and closing tag stay visible as inert text instead of being dropped. Solid, Vue, and React Native previously rendered these tags live unless tagfilter: true was passed explicitly, and escaped output in every renderer stopped at the opener. Direct calls to astToJSX follow the same default.