unified

Project: remarkjs/react-remark

Package: react-remark@2.1.0

  1. Renders Markdown as React components

    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

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