HTML to React Parser
html-to-react is a lightweight JavaScript library designed to convert raw HTML strings into a React DOM structure. Released last as version 1.7.0 approximately six years ago, it primarily serves applications built with older React versions, evidenced by its peer dependency on `react@^0.13.0 || ^0.14.0 || >=15`. While not actively maintained for recent React releases, it provides a solution for embedding React components within existing HTML templates, specifically addressing scenarios where a page includes HTML generated externally but requires certain sections to be managed by React. This avoids the common issue of creating multiple top-level React roots, instead parsing the entire HTML into a single React element tree. Key features include the ability to define custom processing instructions for specific DOM nodes, allowing for fine-grained control over how HTML elements are transformed into React components.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'Parser') or (reading 'ProcessNodeDefinitions')
cause This error typically occurs when named exports (`Parser`, `ProcessNodeDefinitions`) are not correctly imported from the `html-to-react` module, or when attempting to use CommonJS `require` syntax in an ESM-only environment without proper transpilation.fixEnsure you are using `import { Parser, ProcessNodeDefinitions } from 'html-to-react';` for ESM. Verify the package is installed and accessible in your `node_modules`. -
Error: Invariant Violation: Minified React error #XXX; visit https://reactjs.org/docs/error-decoder.html?invariant=XXX for the full message or use the non-minified dev environment for full errors.
cause This generic React invariant violation often indicates a compatibility issue with the React version being used, rendering invalid React elements, or internal inconsistencies due to the `html-to-react` library's old peer dependencies conflicting with modern React's core mechanisms.fixVerify that the `react` version installed in your project aligns with the range specified by `html-to-react`'s peer dependencies. For modern React applications, it's strongly recommended to use a different, actively maintained HTML-to-React parsing library.
Warnings
- breaking The library has very old React peer dependencies (`^0.13.0 || ^0.14.0 || >=15`) and has not been updated in over six years. It is highly unlikely to work without issues with modern React versions (e.g., React 17+ or 18+) due to significant changes in React's internal mechanisms, context API, and rendering lifecycle.
- gotcha The order of `processingInstructions` is critical. Instructions are executed sequentially, and the first `shouldProcessNode` that returns `true` for a given node will have its `processNode` method applied. Subsequent instructions for that node will be ignored.
- gotcha Directly rendering arbitrary user-supplied HTML content can lead to Cross-Site Scripting (XSS) vulnerabilities. While `html-to-react` converts to React elements, it does not inherently sanitize or filter malicious scripts within the HTML input.
- deprecated The library's primary examples and age reflect a reliance on CommonJS `require()` syntax. While CommonJS may still function in some environments, modern JavaScript projects typically utilize ESM `import` statements, which are not directly demonstrated in the original documentation.
Install
-
npm install html-to-react -
yarn add html-to-react -
pnpm add html-to-react
Imports
- Parser
const HtmlToReactParser = require('html-to-react').Parser;import { Parser } from 'html-to-react'; - ProcessNodeDefinitions
const HtmlToReact = require('html-to-react'); const processNodeDefinitions = new HtmlToReact.ProcessNodeDefinitions();import { ProcessNodeDefinitions } from 'html-to-react'; - Type Imports
import type { HtmlToReactParser, ProcessingInstruction, CustomisableNode } from 'html-to-react';
Quickstart
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { Parser, ProcessNodeDefinitions } from 'html-to-react';
interface CustomNode extends Node {
data?: string;
name?: string;
parent?: CustomNode; // Add parent for 'shouldProcessNode' logic
}
const htmlInput = '<div><h1>Title</h1><p>Paragraph</p><h1>Another title</h1></div>';
const htmlExpected = '<div><h1>TITLE</h1><p>Paragraph</p><h1>ANOTHER TITLE</h1></div>';
// A function to determine if a node should be processed
const isValidNode = (node: CustomNode) => true;
// Order of instructions matters: most specific to most general
const processNodeDefinitions = new ProcessNodeDefinitions();
const processingInstructions = [
{
// Custom processing for <h1> tags: capitalize their content
shouldProcessNode: (node: CustomNode) => {
// Check if the node is a child of an <h1> tag and contains text data
return node.parent && node.parent.name === 'h1' && node.type === 'text';
},
processNode: (node: CustomNode) => {
return node.data?.toUpperCase();
}
},
{
// Default processing for all other nodes that haven't been handled
shouldProcessNode: (node: CustomNode) => true,
processNode: processNodeDefinitions.processDefaultNode
}
];
const htmlToReactParser = new Parser();
const reactComponent = htmlToReactParser.parseWithInstructions(
htmlInput,
isValidNode,
processingInstructions
);
// Render the resulting React component tree back to static HTML
const reactHtml = ReactDOMServer.renderToStaticMarkup(reactComponent);
console.log('Original HTML Input:', htmlInput);
console.log('Processed React HTML Output:', reactHtml);
console.log('Assertion (output matches expected):', reactHtml === htmlExpected);