html-to-react
A lightweight library that converts raw HTML to a React DOM structure.
Why?
I had a scenario where an HTML template was generated by a different team, yet I wanted to leverage
React for the parts I did have control over. The template basically contains something like:
I had to replace each
which was nothing more than a React component.
Simply replacing the
React components that have no common parent.
The html-to-react module solves this problem by parsing each DOM element and converting it to a
React tree with one single parent.
Installation
$ npm install --save html-to-react
Examples
Simple
The following example parses each node and its attributes and returns a tree of React elements.
var ReactDOMServer = require('react-dom/server');
var HtmlToReactParser = require('html-to-react').Parser;
var htmlInput = '
Title
A paragraph
var htmlToReactParser = new HtmlToReactParser();
var reactElement = htmlToReactParser.parse(htmlInput);
var reactHtml = ReactDOMServer.renderToStaticMarkup(reactElement);
assert.equal(reactHtml, htmlInput); // true
With Custom Processing Instructions
If certain DOM nodes require specific processing, for example if you want to capitalize each
tag, the following example demonstrates this:
var ReactDOMServer = require('react-dom/server');
var HtmlToReactParser = require('html-to-react').Parser;
var htmlInput = '
Title
Paragraph
Another title
var htmlExpected = '
TITLE
Paragraph
ANOTHER TITLE
var isValidNode = function() {
return true;
};
// Order matters. Instructions are processed in the order they're defined
var processNodeDefinitions = new HtmlToReact.ProcessNodeDefinitions(React);
var processingInstructions = [
{
// Custom
processing
shouldProcessNode: function(node) {
return node.parent && node.parent.name && node.parent.name === 'h1';
},
processNode: function(node, children) {
return node.data.toUpperCase();
}
}, {
// Anything else
shouldProcessNode: function(node) {
return true;
},
processNode: processNodeDefinitions.processDefaultNode
}];
var htmlToReactParser = new HtmlToReactParser();
var reactComponent = htmlToReactParser.parseWithInstructions(htmlInput, isValidNode,
processingInstructions);
var reactHtml = ReactDOMServer.renderToStaticMarkup(reactComponent);
assert.equal(reactHtml, htmlExpected);
Replace the Children of an Element
There may be a situation where you want to replace the children of an element with a React
component. This is beneficial if you want to:
a) Preserve the containing element
b) Not rely on any child node to insert your React component
Example
Below is a simple template that could get loaded via ajax into your application
Before
Sample Heading
Sample Text
After
You may want to extract the inner html from the data-container attribute, store it and then pass
it as a prop to your injected RichTextEditor.
Sample heading
Sample Text
"} />Setup
In your instructions object, you must specify replaceChildren: true.
var React = require('react');
var HtmlToReactParser = require('html-to-react').Parser;
var htmlToReactParser = new HtmlToReactParser();
var htmlInput = '
Text
Text
var htmlExpected = '
Heading
var isValidNode = function() {
return true;
};
// Order matters. Instructions are processed in
// the order they're defined
var processingInstructions = [
{
// This is REQUIRED, it tells the parser
// that we want to insert our React
// component as a child
replaceChildren: true,
shouldProcessNode: function (node) {
return node.attribs && node.attribs['data-test'] === 'foo';
},
processNode: function (node, children, index) {
return React.createElement('h1', {key: index,}, 'Heading');
}
},
{
// Anything else
shouldProcessNode: function (node) {
return true;
},
processNode: processNodeDefinitions.processDefaultNode,
},
];
var reactComponent = parser.parseWithInstructions(
htmlInput, isValidNode, processingInstructions);
var reactHtml = ReactDOMServer.renderToStaticMarkup(
reactComponent);
assert.equal(reactHtml, htmlExpected);
Tests & Coverage
Test locally: $ npm test
Test with coverage and report coverage to Coveralls: $ npm run test-coverage
Test with coverage and open HTML report: $ npm run test-html-coverage