Home

Awesome

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;

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