react-markdown v6.0.0 Release Notes

Release Date: 2021-04-15 // almost 3 years ago
  • Welcome to version 6. πŸš€ This a major release and therefore contains breaking changes.

    πŸ”„ Change renderers to components

    react-markdown used to let you define components for markdown constructs (link, delete, break, etc). This proved complex as users didn’t know about those names or markdown peculiarities (such as that there are fully formed links and link references).

    See GH-549 for more on why this changed. See Appendix B: Components in readme.md for more on components.

    Show example of needed change

    Before (broken):

    <Markdown
      renderers={{
        // Use a fancy hr
        thematicBreak: ({node, ...props}) => <MyFancyRule {...props} />
      }}
    >{`***`}</Markdown>
    

    πŸ›  Now (fixed):

    <Markdown
      components={{
        // Use a fancy hr
        hr: ({node, ...props}) => <MyFancyRule {...props} />
      }}
    >{`***`}</Markdown>
    

    Show conversion table

    Type (renderers) Tag names (components)
    blockquote blockquote
    break br
    code, inlineCode code, pre​*​
    definition †
    delete del‑
    emphasis em
    heading h1, h2, h3, h4, h5, h6Β§
    html, parsedHtml, virtualHtml β€–
    image, imageReference img†
    link, linkReference a†
    list ol, ulΒΆ
    listItem li
    paragraph p
    root ​**​
    strong strong
    table table‑
    tableHead thead‑
    tableBody tbody‑
    tableRow tr‑
    tableCell td, th‑
    text
    thematicBreak hr
    • ​*​ It’s possible to differentiate between code based on the inline prop. Block code is also wrapped in a pre
    • † Resource ([text](url)) and reference ([text][id]) style links and images (and their definitions) are now resolved and treated the same
    • ‑ Available when using remark-gfm
    • Β§ It’s possible to differentiate between heading based on the level prop
    • β€– When using rehype-raw (see below), components for those elements can also be used (for example, abbr for <abbr title="HyperText Markup Language">HTML</abbr>)
    • ΒΆ It’s possible to differentiate between lists based on the ordered prop
    • ​**​ Wrap ReactMarkdown in a component instead

    βž• Add rehypePlugins

    πŸ”Œ We’ve added another plugin system: rehype. It’s similar to remark (what we’re using for markdown) but for HTML.

    πŸ”Œ There are many rehype plugins. Some examples are @mapbox/rehype-prism (syntax highlighting with Prism), πŸ“¦ rehype-katex (rendering math with KaTeX), or rehype-autolink-headings (adding links to headings).

    πŸ‘€ See List of plugins πŸ”Œ for more plugins.

    Show example of feature

    import rehypeHighlight from 'rehype-highlight'
    
    <Markdown rehypePlugins={[rehypeHighlight]}>{`~~~js
    console.log(1)
    ~~~`}</Markdown>
    

    βœ‚ Remove buggy HTML in markdown parser

    In a lot of cases, you should not use HTML in markdown: it’s most always unsafe. And it defeats much of the purpose of this project (not relying on dangerouslySetInnerHTML).

    πŸ“œ react-markdown used to have an opt-in HTML parser with a bunch of bugs. πŸ”Œ As we now support rehype plugins, we can defer that work to a rehype plugin. πŸ‘ To support HTML in markdown with react-markdown, use rehype-raw. πŸ”Œ The astPlugins and allowDangerousHtml (previously called escapeHtml) props 🚚 are no longer needed and were removed.

    When using rehype-raw, you should probably use rehype-sanitize too.

    Show example of needed change

    Before (broken):

    import MarkdownWithHtml from 'react-markdown/with-html'
    
    <MarkdownWithHtml>{`# Hello, <i>world</i>!`}</MarkdownWithHtml>
    

    πŸ›  Now (fixed):

    import Markdown from 'react-markdown'
    import rehypeRaw from 'rehype-raw'
    import rehypeSanitize from 'rehype-sanitize'
    
    <Markdown rehypePlugins={[rehypeRaw, rehypeSanitize]}>{`# Hello, <i>world</i>!`}</Markdown>
    

    πŸ”„ Change source to children

    Instead of passing a source pass children instead:

    Show example of needed change

    Before (broken):

    <Markdown source="some\nmarkdown"></Markdown>
    

    πŸ›  Now (fixed):

    <Markdown>{`some
    markdown`}</Markdown>
    

    πŸ›  Or (also fixed):

    <Markdown children={`some
    markdown`} />
    

    Replace allowNode, allowedTypes, and disallowedTypes

    Similar to the renderers to components change, the filtering options also changed from being based on markdown names towards being based on HTML names: allowNode to allowElement, allowedTypes to allowedElements, and disallowedTypes to disallowedElements.

    Show example of needed change

    Before (broken):

    <Markdown
      // Skip images
      disallowedTypes={['image']}
    >{`![alt text](./image.url)`}</Markdown>
    

    πŸ›  Now (fixed):

    <Markdown
      // Skip images
      disallowedElements={['img']}
    >{`![alt text](./image.url)`}</Markdown>
    

    Before (broken):

    <Markdown
      // Skip h1
      allowNode={(node) => node.type !== 'heading' || node.depth !== 1}
    >{`# main heading`}</Markdown>
    

    πŸ›  Now (fixed):

    <Markdown
      // Skip h1
      allowElement={(element) => element.tagName !== 'h1'}
    >{`# main heading`}</Markdown>
    

    πŸ”„ Change includeNodeIndex to includeElementIndex

    Similar to the renderers to components change, this option to pass more info to components also changed from being based on markdown to being based on HTML.

    Show example of needed change

    Before (broken):

    <Markdown
      includeNodeIndex={true}
      renderers={{
        paragraph({node, index, parentChildCount, ...props}) => <MyFancyParagraph {...props} />
      }}
    >{`Some text`}</Markdown>
    

    πŸ›  Now (fixed):

    <Markdown
      includeElementIndex={true}
      components={{
        p({node, index, siblingsCount, ...props}) => <MyFancyParagraph {...props} />
      }}
    >{`Some text`}</Markdown>
    

    πŸ”„ Change signature of transformLinkUri, linkTarget

    The second parameter of these functions (to rewrite href on a or to define target on a) are now hast (HTML AST) instead of mdast (markdown AST).

    πŸ”„ Change signature of transformImageUri

    The second parameter of this function was always undefined and the fourth was the alt (string) on the image. The second parameter is now that alt.

    βœ‚ Remove support for React 15, IE11

    🚚 We now use ES2015 (such as Object.assign) and removed certain hacks to work with React 15 and older.