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
importReact,{useEffect}from'react';import{useRemark}from'react-remark';constExampleComponent=()=>{const[reactContent,setMarkdownSource]=useRemark();useEffect(()=>{setMarkdownSource('# markdown header');},[]);returnreactContent;};exportdefaultExampleComponent;importReactfrom'react';import{useRemark}from'react-remark';constExampleComponent=()=>{const[reactContent,setMarkdownSource]=useRemark();return(<><inputtype="text"onChange={({ currentTarget })=>setMarkdownSource(currentTarget.value)}/>{reactContent}</>);};exportdefaultExampleComponent;importReactfrom'react';import{useRemarkSync}from'react-remark';constExampleComponent=()=>{constreactContent=useRemarkSync('# markdown header');returnreactContent;};exportdefaultExampleComponent;📓 Note that some remark plugins are async, these plugins will error if used with useRemarkSync.
More examples of usage as hook in storybook.
importReact,{useState}from'react';import{Remark}from'react-remark';constExampleComponent=()=>(<Remark>{`# header1. ordered2. list`}</Remark>);exportdefaultExampleComponent;importReact,{useState}from'react';import{Remark}from'react-remark';constExampleComponent=()=>{const[markdownSource,setMarkdownSource]=useState('');return(<><inputtype="text"onChange={({ currentTarget })=>setMarkdownSource(currentTarget.value)}/><Remark>{markdownSource}</Remark></>);};exportdefaultExampleComponent;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
importReact,{Fragment}from'react';import{useRemark}from'react-remark';importremarkGemojifrom'remark-gemoji';importrehypeSlugfrom'rehype-slug';importrehypeAutoLinkHeadingsfrom'rehype-autolink-headings';// ...const[reactContent,setMarkdownSource]=useRemark({remarkPlugins: [remarkGemoji],remarkToRehypeOptions: {allowDangerousHtml: true},rehypePlugins: [rehypeSlug,rehypeAutoLinkHeadings],rehypeReactOptions: {components: {p: (props)=><pclassName="custom-paragraph"{...props}/>,},},});importReact,{Fragment}from'react';import{Remark}from'react-remark';importremarkGemojifrom'remark-gemoji';importrehypeSlugfrom'rehype-slug';importrehypeAutoLinkHeadingsfrom'rehype-autolink-headings';// ...<RemarkremarkPlugins={[remarkGemoji]}remarkToRehypeOptions={{allowDangerousHtml: true}}rehypePlugins={[rehypeSlug,rehypeAutoLinkHeadings]}rehypeReactOptions={{components: {p: (props)=><pclassName="custom-paragraph"{...props}/>,},}}>{markdownSource}</Remark>;