react-remark offers a React hook and React component based way of rendering markdown into React using remark
npm
npm install --save react-remark yarn
yarn add react-remark import React, { useEffect } from 'react'; import { useRemark } from 'react-remark'; const ExampleComponent = () => { const [reactContent, setMarkdownSource] = useRemark(); useEffect(() => { setMarkdownSource('# markdown header'); }, []); return reactContent; }; export default ExampleComponent;import React from 'react'; import { useRemark } from 'react-remark'; const ExampleComponent = () => { const [reactContent, setMarkdownSource] = useRemark(); return ( <> <input type="text" onChange={({ currentTarget }) => setMarkdownSource(currentTarget.value)} /> {reactContent} </> ); }; export default ExampleComponent;import React from 'react'; import { useRemarkSync } from 'react-remark'; const ExampleComponent = () => { const reactContent = useRemarkSync('# markdown header'); return reactContent; }; export default ExampleComponent;đź““ Note that some remark plugins are async, these plugins will error if used with useRemarkSync.
More examples of usage as hook in storybook.
import React, { useState } from 'react'; import { Remark } from 'react-remark'; const ExampleComponent = () => ( <Remark>{` # header 1. ordered 2. list `}</Remark> ); export default ExampleComponent;import React, { useState } from 'react'; import { Remark } from 'react-remark'; const ExampleComponent = () => { const [markdownSource, setMarkdownSource] = useState(''); return ( <> <input type="text" onChange={({ currentTarget }) => setMarkdownSource(currentTarget.value)} /> <Remark>{markdownSource}</Remark> </> ); }; export default ExampleComponent;More examples of usage as component in storybook.
A set of runnable examples are provided through storybook at https://remarkjs.github.io/react-remark. The source for the story files can be found in /stories.
react-remark +---------------------------------------------------------------------------------------------------------------------------------------------+ | | | +----------+ +----------------+ +---------------+ +----------------+ +--------------+ | | | | | | | | | | | | | | -markdown->+ remark +-mdast->+ remark plugins +-mdast->+ remark-rehype +-hast->+ rehype plugins +-hast->+ rehype-react +-react elements-> | | | | | | | | | | | | | | +----------+ +----------------+ +---------------+ +----------------+ +--------------+ | | | +---------------------------------------------------------------------------------------------------------------------------------------------+ relevant links: markdown, remark, mdast, remark plugins, remark-rehype, hast, rehype plugins, rehype-react
remarkParseOptions(Object) - configure how Markdown is parsed, same asremark-parseoptionsremarkPlugins(Array) - remark plugins or custom plugins to transform markdown content before it is translated to HTML (hast)remarkToRehypeOptions(Object) - configure how Markdown (mdast) is translated into HTML (hast), same asremark-rehypeoptionsrehypePlugins(Array) - rehype plugins or custom plugins to transform HTML (hast) before it is translated to React elements.rehypeReactOptions(Object) - configure how HTML (hast) is translated into React elements, same asrehype-reactoptions
import React, { Fragment } from 'react'; import { useRemark } from 'react-remark'; import remarkGemoji from 'remark-gemoji'; import rehypeSlug from 'rehype-slug'; import rehypeAutoLinkHeadings from 'rehype-autolink-headings'; // ... const [reactContent, setMarkdownSource] = useRemark({ remarkPlugins: [remarkGemoji], remarkToRehypeOptions: { allowDangerousHtml: true }, rehypePlugins: [rehypeSlug, rehypeAutoLinkHeadings], rehypeReactOptions: { components: { p: (props) => <p className="custom-paragraph" {...props} />, }, }, });import React, { Fragment } from 'react'; import { Remark } from 'react-remark'; import remarkGemoji from 'remark-gemoji'; import rehypeSlug from 'rehype-slug'; import rehypeAutoLinkHeadings from 'rehype-autolink-headings'; // ... <Remark remarkPlugins={[remarkGemoji]} remarkToRehypeOptions={{ allowDangerousHtml: true }} rehypePlugins={[rehypeSlug, rehypeAutoLinkHeadings]} rehypeReactOptions={{ components: { p: (props) => <p className="custom-paragraph" {...props} />, }, }} > {markdownSource} </Remark>;