Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork135
remarkablemark/html-react-parser
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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 moreReact elements.
To replace an element with another element, check out thereplace
option.
importparsefrom'html-react-parser';parse('<p>Hello, World!</p>');// React.createElement('p', {}, 'Hello, World!')
Replit |JSFiddle |StackBlitz |TypeScript |Examples
Table of Contents
- Install
- Usage
- Migration
- FAQ
- Is this XSS safe?
- Does invalid HTML get sanitized?
- Are
<script>
tags parsed? - Attributes aren't getting called
- Parser throws an error
- Is SSR supported?
- Elements aren't nested correctly
- Don't change case of tags
- TS Error: Property 'attribs' does not exist on type 'DOMNode'
- Can I enable
trim
for certain elements? - Webpack build warnings
- TypeScript error
- Performance
- Contributors
- Support
- License
NPM:
npm install html-react-parser --save
Yarn:
yarn add html-react-parser
CDN:
<!-- HTMLReactParser depends on React --><scriptsrc="https://unpkg.com/react@18/umd/react.production.min.js"></script><scriptsrc="https://unpkg.com/html-react-parser@latest/dist/html-react-parser.min.js"></script><script>window.HTMLReactParser(/* string */);</script>
Import ES module:
importparsefrom'html-react-parser';
Or require CommonJS module:
constparse=require('html-react-parser').default;
Parse single element:
parse('<h1>single</h1>');
Parse multiple elements:
parse('<li>Item 1</li><li>Item 2</li>');
Make sure to render parsed adjacent elements under a parent element:
<ul>{parse(` <li>Item 1</li> <li>Item 2</li> `)}</ul>
Parse nested elements:
parse('<body><p>Lorem ipsum</p></body>');
Parse element with attributes:
parse('<hr data-attr="baz" custom="qux">',);
Thereplace
option allows you to replace an element with another element.
Thereplace
callback's first argument isdomhandler's node:
parse('<br>',{replace(domNode){console.dir(domNode,{depth:null});},});
Console output
Element{type:'tag',parent:null,prev:null,next:null,startIndex:null,endIndex:null,children:[],name:'br',attribs:{}}
The element is replaced if avalid React element is returned:
parse('<p>text</p>',{replace(domNode){if(domNode.attribs&&domNode.attribs.id==='replace'){return<span>replaced</span>;}},});
The second argument is the index:
parse('<br>',{replace(domNode,index){console.assert(typeofindex==='number');},});
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 thatdomNode
is an instance of domhandler'sElement
:
import{HTMLReactParserOptions,Element}from'html-react-parser';constoptions:HTMLReactParserOptions={replace(domNode){if(domNodeinstanceofElement&&domNode.attribs){// ...}},};
Or use a type assertion:
import{HTMLReactParserOptions,Element}from'html-react-parser';constoptions:HTMLReactParserOptions={replace(domNode){if((domNodeasElement).attribs){// ...}},};
If you're having issues, take a look at ourCreate React App example.
Replace the element and its children (seedemo):
importparse,{domToReact}from'html-react-parser';consthtml=` <p> <span> keep me and make me pretty! </span> </p>`;constoptions={replace({ attribs, children}){if(!attribs){return;}if(attribs.id==='main'){return<h1style={{fontSize:42}}>{domToReact(children,options)}</h1>;}if(attribs.class==='prettify'){return(<spanstyle={{color:'hotpink'}}>{domToReact(children,options)}</span>);}},};parse(html,options);
HTML output
<h1style="font-size:42px"><spanstyle="color:hotpink"> keep me and make me pretty!</span></h1>
Convert DOM attributes to React props withattributesToProps
:
importparse,{attributesToProps}from'html-react-parser';consthtml=` <main />`;constoptions={replace(domNode){if(domNode.attribs&&domNode.name==='main'){constprops=attributesToProps(domNode.attribs);return<div{...props}/>;}},};parse(html,options);
HTML output
<divclass="prettify"style="background:#fff;text-align:center"></div>
Exclude an element from rendering by replacing it with<React.Fragment>
:
parse('<p><br></p>',{replace:({ attribs})=>attribs?.id==='remove'&&<></>,});
HTML output
<p></p>
Thetransform
option allows you to transform each element individually after it's parsed.
Thetransform
callback's first argument is the React element:
parse('<br>',{transform(reactNode,domNode,index){// this will wrap every element in a divreturn<div>{reactNode}</div>;},});
Thelibrary
option specifies the UI library. The default library isReact.
To use Preact:
parse('<br>',{library:require('preact'),});
Or a custom library:
parse('<br>',{library:{cloneElement:()=>{/* ... */},createElement:()=>{/* ... */},isValidElement:()=>{/* ... */},},});
Warning
htmlparser2
optionsdon't work on the client-side (browser); theyonly work on the server-side (Node.js). By overriding the options, it can break universal rendering.
Defaulthtmlparser2 options can be overridden in >=0.12.0.
To enablexmlMode
:
parse('<p /><p />',{htmlparser2:{xmlMode:true,},});
By default, whitespace is preserved:
parse('<br>\n');// [React.createElement('br'), '\n']
But certain elements like<table>
will strip out invalid whitespace:
parse('<table>\n</table>');// React.createElement('table')
To remove whitespace, enable thetrim
option:
parse('<br>\n',{trim:true});// React.createElement('br')
However, intentional whitespace may be stripped out:
parse('<p> </p>',{trim:true});// React.createElement('p')
Migrated to TypeScript. CommonJS imports require the.default
key:
constparse=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:
domToReact(domNode.childrenasDOMNode[],options);
See#1126.
htmlparser2 has been upgraded tov9.
domhandler has been upgraded to v5 so someparser options likenormalizeWhitespace
have been removed.
Also, it's recommended to upgrade to the latest version ofTypeScript.
Sincev2.0.0, Internet Explorer (IE) is no longer supported.
TypeScript projects will need to update the types inv1.0.0.
For thereplace
option, you may need to do the following:
import{Element}from'domhandler/lib/node';parse('<br>',{replace(domNode){if(domNodeinstanceofElement&&domNode.attribs.class==='remove'){return<></>;}},});
Sincev1.1.1, Internet Explorer 9 (IE9) is no longer supported.
No, this library isnotXSS (cross-site scripting) safe. See#94.
No, this library doesnot sanitize HTML. See#124,#125, and#141.
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 becauseinline event handlers (e.g.,onclick
) are parsed as astring rather than afunction. 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. Seedemo.
If your elements are nested incorrectly, check to make sure yourHTML markup is valid. The HTML to DOM parsing will be affected if you're using self-closing syntax (/>
) on non-void elements:
parse('<div /><div />');// returns single element instead of array of elements
See#158.
Tags are lowercased by default. To prevent that from happening, pass thehtmlparser2 option:
constoptions={htmlparser2:{lowerCaseTags:false,},};parse('<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 becauseDOMNode
needs to be an instance of domhandler'sElement
. Seemigration or#199.
Yes, you can enable or disabletrim
for certain elements using thereplace
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:
// webpack.config.jsmodule.exports={// ...resolve:{mainFields:['browser','main','module'],},};
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 oftypescript. See#748.
Run benchmark:
npm 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)
RunSize Limit:
npx 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]
About
📝 HTML to React parser.
Topics
Resources
License
Code of conduct
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.