Gathering detailed insights and metrics for html-react-parser
Gathering detailed insights and metrics for html-react-parser
Gathering detailed insights and metrics for html-react-parser
Gathering detailed insights and metrics for html-react-parser
tiptap-parser
HTML parser to React component built on the top of html-react-parser with code syntax highlighting
react-html-parser
Parse HTML into React components
node-html-parser
A very fast HTML parser, generating a simplified DOM, with basic element query support.
sax
An evented streaming XML parser in JavaScript
npm install html-react-parser
59.2
Supply Chain
98.4
Quality
88.1
Maintenance
100
Vulnerability
100
License
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
2,155 Stars
2,717 Commits
130 Forks
6 Watching
1 Branches
33 Contributors
Updated on 27 Nov 2024
Minified
Minified + Gzipped
TypeScript (89.3%)
JavaScript (10.7%)
Cumulative downloads
Total Downloads
Last day
-6.5%
288,113
Compared to previous day
Last week
1.2%
1,585,358
Compared to previous week
Last month
5.4%
6,745,914
Compared to previous month
Last year
42.6%
71,799,329
Compared to previous year
4
2
34
HTML to React parser that works on both the server (Node.js) and the client (browser):
HTMLReactParser(string[, options])
The parser converts an HTML string to one or more React elements.
To replace an element with another element, check out the replace
option.
1import parse from 'html-react-parser'; 2 3parse('<p>Hello, World!</p>'); // React.createElement('p', {}, 'Hello, World!')
Replit | JSFiddle | StackBlitz | TypeScript | Examples
<script>
tags parsed?trim
for certain elements?NPM:
1npm install html-react-parser --save
Yarn:
1yarn add html-react-parser
CDN:
1<!-- HTMLReactParser depends on React --> 2<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> 3<script src="https://unpkg.com/html-react-parser@latest/dist/html-react-parser.min.js"></script> 4<script> 5 window.HTMLReactParser(/* string */); 6</script>
Import ES module:
1import parse from 'html-react-parser';
Or require CommonJS module:
1const parse = require('html-react-parser').default;
Parse single element:
1parse('<h1>single</h1>');
Parse multiple elements:
1parse('<li>Item 1</li><li>Item 2</li>');
Make sure to render parsed adjacent elements under a parent element:
1<ul> 2 {parse(` 3 <li>Item 1</li> 4 <li>Item 2</li> 5 `)} 6</ul>
Parse nested elements:
1parse('<body><p>Lorem ipsum</p></body>');
Parse element with attributes:
1parse( 2 '<hr id="foo" class="bar" data-attr="baz" custom="qux" style="top:42px;">', 3);
The replace
option allows you to replace an element with another element.
The replace
callback's first argument is domhandler's node:
1parse('<br>', { 2 replace(domNode) { 3 console.dir(domNode, { depth: null }); 4 }, 5});
1Element { 2 type: 'tag', 3 parent: null, 4 prev: null, 5 next: null, 6 startIndex: null, 7 endIndex: null, 8 children: [], 9 name: 'br', 10 attribs: {} 11}
The element is replaced if a valid React element is returned:
1parse('<p id="replace">text</p>', { 2 replace(domNode) { 3 if (domNode.attribs && domNode.attribs.id === 'replace') { 4 return <span>replaced</span>; 5 } 6 }, 7});
The second argument is the index:
1parse('<br>', { 2 replace(domNode, index) { 3 console.assert(typeof index === 'number'); 4 }, 5});
[!NOTE] The index will restart at 0 when traversing the node's children so don't rely on index being a unique key. See #1259.
You need to check that domNode
is an instance of domhandler's Element
:
1import { HTMLReactParserOptions, Element } from 'html-react-parser'; 2 3const options: HTMLReactParserOptions = { 4 replace(domNode) { 5 if (domNode instanceof Element && domNode.attribs) { 6 // ... 7 } 8 }, 9};
Or use a type assertion:
1import { HTMLReactParserOptions, Element } from 'html-react-parser'; 2 3const options: HTMLReactParserOptions = { 4 replace(domNode) { 5 if ((domNode as Element).attribs) { 6 // ... 7 } 8 }, 9};
If you're having issues, take a look at our Create React App example.
Replace the element and its children (see demo):
1import parse, { domToReact } from 'html-react-parser'; 2 3const html = ` 4 <p id="main"> 5 <span class="prettify"> 6 keep me and make me pretty! 7 </span> 8 </p> 9`; 10 11const options = { 12 replace({ attribs, children }) { 13 if (!attribs) { 14 return; 15 } 16 17 if (attribs.id === 'main') { 18 return <h1 style={{ fontSize: 42 }}>{domToReact(children, options)}</h1>; 19 } 20 21 if (attribs.class === 'prettify') { 22 return ( 23 <span style={{ color: 'hotpink' }}> 24 {domToReact(children, options)} 25 </span> 26 ); 27 } 28 }, 29}; 30 31parse(html, options);
1<h1 style="font-size:42px"> 2 <span style="color:hotpink"> 3 keep me and make me pretty! 4 </span> 5</h1>
Convert DOM attributes to React props with attributesToProps
:
1import parse, { attributesToProps } from 'html-react-parser'; 2 3const html = ` 4 <main class="prettify" style="background: #fff; text-align: center;" /> 5`; 6 7const options = { 8 replace(domNode) { 9 if (domNode.attribs && domNode.name === 'main') { 10 const props = attributesToProps(domNode.attribs); 11 return <div {...props} />; 12 } 13 }, 14}; 15 16parse(html, options);
1<div class="prettify" style="background:#fff;text-align:center"></div>
Exclude an element from rendering by replacing it with <React.Fragment>
:
1parse('<p><br id="remove"></p>', { 2 replace: ({ attribs }) => attribs?.id === 'remove' && <></>, 3});
1<p></p>
The transform
option allows you to transform each element individually after it's parsed.
The transform
callback's first argument is the React element:
1parse('<br>', { 2 transform(reactNode, domNode, index) { 3 // this will wrap every element in a div 4 return <div>{reactNode}</div>; 5 }, 6});
The library
option specifies the UI library. The default library is React.
To use Preact:
1parse('<br>', { 2 library: require('preact'), 3});
Or a custom library:
1parse('<br>', { 2 library: { 3 cloneElement: () => { 4 /* ... */ 5 }, 6 createElement: () => { 7 /* ... */ 8 }, 9 isValidElement: () => { 10 /* ... */ 11 }, 12 }, 13});
[!WARNING]
htmlparser2
options don't work on the client-side (browser); they only work on the server-side (Node.js). By overriding the options, it can break universal rendering.
Default htmlparser2 options can be overridden in >=0.12.0.
To enable xmlMode
:
1parse('<p /><p />', { 2 htmlparser2: { 3 xmlMode: true, 4 }, 5});
By default, whitespace is preserved:
1parse('<br>\n'); // [React.createElement('br'), '\n']
But certain elements like <table>
will strip out invalid whitespace:
1parse('<table>\n</table>'); // React.createElement('table')
To remove whitespace, enable the trim
option:
1parse('<br>\n', { trim: true }); // React.createElement('br')
However, intentional whitespace may be stripped out:
1parse('<p> </p>', { trim: true }); // React.createElement('p')
Migrated to TypeScript. CommonJS imports require the .default
key:
1const parse = require('html-react-parser').default;
If you're getting the error:
Argument of type 'ChildNode[]' is not assignable to parameter of type 'DOMNode[]'.
Then use type assertion:
1domToReact(domNode.children as DOMNode[], options);
See #1126.
htmlparser2 has been upgraded to v9.
domhandler has been upgraded to v5 so some parser options like normalizeWhitespace
have been removed.
Also, it's recommended to upgrade to the latest version of TypeScript.
Since v2.0.0, Internet Explorer (IE) is no longer supported.
TypeScript projects will need to update the types in v1.0.0.
For the replace
option, you may need to do the following:
1import { Element } from 'domhandler/lib/node'; 2 3parse('<br class="remove">', { 4 replace(domNode) { 5 if (domNode instanceof Element && domNode.attribs.class === 'remove') { 6 return <></>; 7 } 8 }, 9});
Since v1.1.1, Internet Explorer 9 (IE9) is no longer supported.
No, this library is not XSS (cross-site scripting) safe. See #94.
No, this library does not sanitize HTML. See #124, #125, and #141.
<script>
tags parsed?Although <script>
tags and their contents are rendered on the server-side, they're not evaluated on the client-side. See #98.
The reason why your HTML attributes aren't getting called is because inline event handlers (e.g., onclick
) are parsed as a string rather than a function. See #73.
If the parser throws an error, check if your arguments are valid. See "Does invalid HTML get sanitized?".
Yes, server-side rendering on Node.js is supported by this library. See demo.
If your elements are nested incorrectly, check to make sure your HTML markup is valid. The HTML to DOM parsing will be affected if you're using self-closing syntax (/>
) on non-void elements:
1parse('<div /><div />'); // returns single element instead of array of elements
See #158.
Tags are lowercased by default. To prevent that from happening, pass the htmlparser2 option:
1const options = { 2 htmlparser2: { 3 lowerCaseTags: false, 4 }, 5}; 6parse('<CustomElement>', options); // React.createElement('CustomElement')
[!WARNING] By preserving case-sensitivity of the tags, you may get rendering warnings like:
Warning: <CustomElement> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
The TypeScript error occurs because DOMNode
needs to be an instance of domhandler's Element
. See migration or #199.
trim
for certain elements?Yes, you can enable or disable trim
for certain elements using the replace
option. See #205.
If you see the Webpack build warning:
export 'default' (imported as 'parse') was not found in 'html-react-parser'
Then update your Webpack config to:
1// webpack.config.js 2module.exports = { 3 // ... 4 resolve: { 5 mainFields: ['browser', 'main', 'module'], 6 }, 7};
If you see the TypeScript error:
node_modules/htmlparser2/lib/index.d.ts:2:23 - error TS1005: ',' expected.
2 export { Parser, type ParserOptions };
~~~~~~~~~~~~~
Then upgrade to the latest version of typescript. See #748.
Run benchmark:
1npm run benchmark
Output of benchmark run on MacBook Pro 2021:
html-to-react - Single x 1,018,239 ops/sec ±0.43% (94 runs sampled)
html-to-react - Multiple x 380,037 ops/sec ±0.61% (97 runs sampled)
html-to-react - Complex x 35,091 ops/sec ±0.50% (96 runs sampled)
Run Size Limit:
1npx size-limit
This project exists thanks to all the people who contribute. [Contribute].
Become a financial contributor and help us sustain our community. [Contribute]
Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
24 out of 24 merged PRs checked by a CI test -- score normalized to 10
Reason
project has 15 contributing companies or organizations
Details
Reason
no dangerous workflow patterns detected
Reason
update tool detected
Details
Reason
license file detected
Details
Reason
30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Reason
packaging workflow detected
Details
Reason
SAST tool is run on all commits
Details
Reason
security policy file detected
Details
Reason
1 existing vulnerabilities detected
Details
Reason
branch protection is not maximal on development and all release branches
Details
Reason
dependency not pinned by hash detected -- score normalized to 3
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
Found 0/5 approved changesets -- score normalized to 0
Reason
project is not fuzzed
Details
Reason
detected GitHub workflow tokens with excessive permissions
Details
Score
Last Scanned on 2024-11-27T03:42:33Z
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More