UNPKG

10.4 kBMarkdownView Raw
1# rehype-react
2
3[![Build][build-badge]][build]
4[![Coverage][coverage-badge]][coverage]
5[![Downloads][downloads-badge]][downloads]
6[![Size][size-badge]][size]
7[![Sponsors][sponsors-badge]][collective]
8[![Backers][backers-badge]][collective]
9[![Chat][chat-badge]][chat]
10
11**[rehype][]** plugin to turn HTML into preact, react, solid, svelte, vue, etc.
12
13## Contents
14
15* [What is this?](#what-is-this)
16* [When should I use this?](#when-should-i-use-this)
17* [Install](#install)
18* [Use](#use)
19* [API](#api)
20 * [`unified().use(rehypeReact, options)`](#unifieduserehypereact-options)
21 * [`Components`](#components)
22 * [`Options`](#options)
23* [Types](#types)
24* [Compatibility](#compatibility)
25* [Security](#security)
26* [Related](#related)
27* [Contribute](#contribute)
28* [License](#license)
29
30## What is this?
31
32This package is a [unified][] ([rehype][]) plugin that compiles HTML (hast) to
33any JSX runtime (preact, react, solid, svelte, vue, etc).
34
35**unified** is a project that transforms content with abstract syntax trees
36(ASTs).
37**rehype** adds support for HTML to unified.
38**hast** is the HTML AST that rehype uses.
39This is a rehype plugin that adds a compiler to compile hast to a JSX runtime.
40
41## When should I use this?
42
43This plugin adds a compiler for rehype, which means that it turns the final
44HTML (hast) syntax tree into something else (in this case, a `JSX.Element`).
45It’s useful when you’re already using unified (whether remark or rehype) or are
46open to learning about ASTs (they’re powerful!) and want to render content in
47your app.
48
49If you’re not familiar with unified, then [`react-markdown`][react-markdown]
50might be a better fit.
51You can also use [`react-remark`][react-remark] instead, which is somewhere
52between `rehype-react` and `react-markdown`, as it does more that the former and
53is more modern (such as supporting hooks) than the latter, and also a good
54alternative.
55If you want to use JavaScript and JSX *inside* markdown files, use [MDX][].
56
57## Install
58
59This package is [ESM only][esm].
60In Node.js (version 16+), install with [npm][]:
61
62```sh
63npm install rehype-react
64```
65
66In Deno with [`esm.sh`][esmsh]:
67
68```js
69import rehypeReact from 'https://esm.sh/rehype-react@8'
70```
71
72In browsers with [`esm.sh`][esmsh]:
73
74```html
75<script type="module">
76 import rehypeReact from 'https://esm.sh/rehype-react@8?bundle'
77</script>
78```
79
80## Use
81
82Say our React app `example.js` looks as follows:
83
84```js
85import {Fragment, createElement, useEffect, useState} from 'react'
86import * as prod from 'react/jsx-runtime'
87import rehypeParse from 'rehype-parse'
88import rehypeReact from 'rehype-react'
89import {unified} from 'unified'
90
91// @ts-expect-error: the react types are missing.
92const production = {Fragment: prod.Fragment, jsx: prod.jsx, jsxs: prod.jsxs}
93
94const text = `<h2>Hello, world!</h2>
95<p>Welcome to my page 👀</p>`
96
97/**
98 * @param {string} text
99 * @returns {JSX.Element}
100 */
101function useProcessor(text) {
102 const [Content, setContent] = useState(createElement(Fragment))
103
104 useEffect(
105 function () {
106 ;(async function () {
107 const file = await unified()
108 .use(rehypeParse, {fragment: true})
109 .use(rehypeReact, production)
110 .process(text)
111
112 setContent(file.result)
113 })()
114 },
115 [text]
116 )
117
118 return Content
119}
120
121export default function App() {
122 return useProcessor(text)
123}
124```
125
126…running that in Next.js or similar, we’d get:
127
128```html
129<h2>Hello, world!</h2>
130<p>Welcome to my page 👀</p>
131```
132
133## API
134
135This package exports no identifiers.
136The default export is [`rehypeReact`][api-rehype-react].
137
138### `unified().use(rehypeReact, options)`
139
140Turn HTML into preact, react, solid, svelte, vue, etc.
141
142###### Parameters
143
144* `options` ([`Options`][api-options], required)
145 — configuration
146
147###### Returns
148
149Nothing (`undefined`).
150
151###### Result
152
153This plugin registers a compiler that returns a `JSX.Element` where compilers
154typically return `string`.
155When using `.stringify` on `unified`, the result is such a `JSX.Element`.
156When using `.process` (or `.processSync`), the result is available at
157`file.result`.
158
159###### Frameworks
160
161There are differences between what JSX frameworks accept, such as whether they
162accept `class` or `className`, or `background-color` or `backgroundColor`.
163
164For hast elements transformed by this project, this is be handled through
165options:
166
167| Framework | `elementAttributeNameCase` | `stylePropertyNameCase` |
168| --------- | -------------------------- | ----------------------- |
169| Preact | `'html'` | `'dom'` |
170| React | `'react'` | `'dom'` |
171| Solid | `'html'` | `'css'` |
172| Vue | `'html'` | `'dom'` |
173
174### `Components`
175
176Possible components to use (TypeScript type).
177
178See [`Components` from
179`hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime#components)
180for more info.
181
182### `Options`
183
184Configuration (TypeScript type).
185
186###### Fields
187
188* `Fragment` ([`Fragment` from
189 `hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime#fragment),
190 required)
191 — fragment
192* `jsx` ([`Jsx` from
193 `hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime#jsx),
194 required in production)
195 — dynamic JSX
196* `jsxs` ([`Jsx` from
197 `hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime#jsx),
198 required in production)
199 — static JSX
200* `jsxDEV` ([`JsxDev` from
201 `hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime#jsxdev),
202 required in development)
203 — development JSX
204* `components` ([`Partial<Components>`][api-components], optional)
205 — components to use
206* `development` (`boolean`, default: `false`)
207 — whether to use `jsxDEV` when on or `jsx` and `jsxs` when off
208* `elementAttributeNameCase` (`'html'` or `'react'`, default: `'react'`)
209 — specify casing to use for attribute names
210* `passNode` (`boolean`, default: `false`)
211 — pass the hast element node to components
212* `space` (`'html'` or `'svg'`, default: `'html'`)
213 — whether `tree` is in the `'html'` or `'svg'` space, when an `<svg>`
214 element is found in the HTML space, this package already automatically
215 switches to and from the SVG space when entering and exiting it
216* `stylePropertyNameCase`
217 (`'css'` or `'dom'`, default: `'dom'`)
218 — specify casing to use for property names in `style` objects
219* `tableCellAlignToStyle`
220 (`boolean`, default: `true`)
221 — turn obsolete `align` props on `td` and `th` into CSS `style` props
222
223## Types
224
225This package is fully typed with [TypeScript][].
226It exports the additional types [`Components`][api-components] and
227[`Options`][api-options].
228More advanced types are exposed from
229[`hast-util-to-jsx-runtime`][hast-util-to-jsx-runtime].
230
231## Compatibility
232
233Projects maintained by the unified collective are compatible with maintained
234versions of Node.js.
235
236When we cut a new major release, we drop support for unmaintained versions of
237Node.
238This means we try to keep the current release line, `rehype-react@^8`,
239compatible with Node.js 17.
240
241This plugin works with `rehype-parse` version 3+, `rehype` version 4+, and
242`unified` version 9+, and React 18+.
243
244## Security
245
246Use of `rehype-react` can open you up to a [cross-site scripting (XSS)][xss]
247attack if the tree is unsafe.
248Use [`rehype-sanitize`][rehype-sanitize] to make the tree safe.
249
250## Related
251
252* [`remark-rehype`](https://github.com/remarkjs/remark-rehype)
253 — turn markdown into HTML to support rehype
254* [`rehype-remark`](https://github.com/rehypejs/rehype-remark)
255 — turn HTML into markdown to support remark
256* [`rehype-retext`](https://github.com/rehypejs/rehype-retext)
257 — rehype plugin to support retext
258* [`rehype-sanitize`][rehype-sanitize]
259 — sanitize HTML
260
261## Contribute
262
263See [`contributing.md`][contributing] in [`rehypejs/.github`][health] for ways
264to get started.
265See [`support.md`][support] for ways to get help.
266
267This project has a [code of conduct][coc].
268By interacting with this repository, organization, or community you agree to
269abide by its terms.
270
271## License
272
273[MIT][license] © [Titus Wormer][titus], modified by [Tom MacWright][tom],
274[Mapbox][], and [rhysd][].
275
276<!-- Definitions -->
277
278[build-badge]: https://github.com/rehypejs/rehype-react/workflows/main/badge.svg
279
280[build]: https://github.com/rehypejs/rehype-react/actions
281
282[coverage-badge]: https://img.shields.io/codecov/c/github/rehypejs/rehype-react.svg
283
284[coverage]: https://codecov.io/github/rehypejs/rehype-react
285
286[downloads-badge]: https://img.shields.io/npm/dm/rehype-react.svg
287
288[downloads]: https://www.npmjs.com/package/rehype-react
289
290[size-badge]: https://img.shields.io/bundlejs/size/rehype-react
291
292[size]: https://bundlejs.com/?q=rehype-react
293
294[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
295
296[backers-badge]: https://opencollective.com/unified/backers/badge.svg
297
298[collective]: https://opencollective.com/unified
299
300[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
301
302[chat]: https://github.com/rehypejs/rehype/discussions
303
304[npm]: https://docs.npmjs.com/cli/install
305
306[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
307
308[esmsh]: https://esm.sh
309
310[health]: https://github.com/rehypejs/.github
311
312[contributing]: https://github.com/rehypejs/.github/blob/main/contributing.md
313
314[support]: https://github.com/rehypejs/.github/blob/main/support.md
315
316[coc]: https://github.com/rehypejs/.github/blob/main/code-of-conduct.md
317
318[license]: license
319
320[titus]: https://wooorm.com
321
322[tom]: https://macwright.org
323
324[mapbox]: https://www.mapbox.com
325
326[rhysd]: https://rhysd.github.io
327
328[hast-util-to-jsx-runtime]: https://github.com/syntax-tree/hast-util-to-jsx-runtime
329
330[mdx]: https://github.com/mdx-js/mdx/
331
332[react-markdown]: https://github.com/remarkjs/react-markdown
333
334[react-remark]: https://github.com/remarkjs/react-remark
335
336[rehype]: https://github.com/rehypejs/rehype
337
338[rehype-sanitize]: https://github.com/rehypejs/rehype-sanitize
339
340[typescript]: https://www.typescriptlang.org
341
342[unified]: https://github.com/unifiedjs/unified
343
344[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
345
346[api-components]: #components
347
348[api-options]: #options
349
350[api-rehype-react]: #unifieduserehypereact-options