react-markdown
Advanced tools
Changelog
7.1.0 - 2021-10-21
7b8a829
Add support for SpecialComponents
to be any ComponentType
a7c26fc
Remove warning on whitespace in tablesChangelog
6.0.0 - 2021-04-15
Welcome to version 6. This a major release and therefore contains breaking changes.
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.
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>
</details>
<details>
<summary>Show conversion table</summary>
| 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
|
inline
prop.
Block code is also wrapped in a pre
[text](url)
) and reference ([text][id]
) style links and
images (and their definitions) are now resolved and treated the sameremark-gfm
level
proprehype-raw
(see below), components for those elements
can also be used (for example, abbr
for
<abbr title="HyperText Markup Language">HTML</abbr>
)ordered
propReactMarkdown
in a component insteadrehypePlugins
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.
<details> <summary>Show example of feature</summary>import rehypeHighlight from 'rehype-highlight'
<Markdown rehypePlugins={[rehypeHighlight]}>{`~~~js
console.log(1)
~~~`}</Markdown>
</details>
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.
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>
</details>
source
to children
Instead of passing a source
pass children
instead:
Before (broken):
<Markdown source="some\nmarkdown"></Markdown>
Now (fixed):
<Markdown>{`some
markdown`}</Markdown>
Or (also fixed):
<Markdown children={`some
markdown`} />
</details>
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
.
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>
</details>
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.
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>
</details>
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).
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
.
We now use ES2015 (such as Object.assign
) and removed certain hacks to work
with React 15 and older.