Skip to content

remarkjs/react-remark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

react-remark

CI Downloads Size

react-remark offers a React hook and React component based way of rendering markdown into React using remark

Installation

npm

npm install --save react-remark 

yarn

yarn add react-remark 

Usage

As a hook

Render static content

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;

Using input and events to update

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;

Server side rendering

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.

As a component

Render static content

import React, { useState } from 'react'; import { Remark } from 'react-remark'; const ExampleComponent = () => ( <Remark>{` # header  1. ordered 2. list `}</Remark> ); export default ExampleComponent;

Using input and events to update

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.

Examples

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.

Architecture

 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

Options

  • remarkParseOptions (Object) - configure how Markdown is parsed, same as remark-parse options
  • remarkPlugins (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 as remark-rehype options
  • rehypePlugins (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 as rehype-react options

Pass options to hook

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} />, }, }, });

Pass options to component

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>;