Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    html-to-reactpublic

    html-to-react

    Greenkeeper badge Build Status npm version Dependency Status Coverage Status npm

    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:

    <div class="row">
        <div class="col-sm-6">
            <div data-report-id="report-1">
              <!-- A React component for report-1 -->
            </div>
        </div>
        <div class="col-sm-6">
            <div data-report-id="report-2">
              <!-- A React component for report-2 -->
            </div>
        </div>
    </div>
    

    I had to replace each <div> that contains a data-report-id attribute with an actual report, which was nothing more than a React component.

    Simply replacing the <div> elements with a React component would end up with multiple top-level 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 = '<div><h1>Title</h1><p>A paragraph</p></div>';
    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 <h1> tag, the following example demonstrates this:

    var ReactDOMServer = require('react-dom/server');
    var HtmlToReact = require('html-to-react');
    var HtmlToReactParser = require('html-to-react').Parser;
     
    var htmlInput = '<div><h1>Title</h1><p>Paragraph</p><h1>Another title</h1></div>';
    var htmlExpected = '<div><h1>TITLE</h1><p>Paragraph</p><h1>ANOTHER TITLE</h1></div>';
     
    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 <h1> 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
    <div class="row">
        <div class="col-sm-6">
            <div data-container="wysiwyg">
                <h1>Sample Heading</h1>
                <p>Sample Text</p>
            </div>
        </div>
    </div>
    
    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.

    <div class="row">
        <div class="col-sm-6">
            <div data-container="wysiwyg">
                <RichTextEditor html={"<h1>Sample heading</h1><p>Sample Text</p>"} />
            </div>
        </div>
    </div>
    

    Setup

    In your instructions object, you must specify replaceChildren: true.

    var React = require('react');
    var HtmlToReact = require('html-to-react');
    var HtmlToReactParser = require('html-to-react').Parser;
     
    var htmlToReactParser = new HtmlToReactParser();
    var htmlInput = '<div><div data-test="foo"><p>Text</p><p>Text</p></div></div>';
    var htmlExpected = '<div><div data-test="foo"><h1>Heading</h1></div></div>';
     
    var isValidNode = function () {
        return true;
    };
     
    var processNodeDefinitions = new HtmlToReact.ProcessNodeDefinitions(React);
     
    // 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

    install

    npm i html-to-react

    Downloadslast 7 days

    9,086

    version

    1.3.3

    license

    MIT

    repository

    github.com

    last publish

    collaborators

    • avatar
    • avatar
    • avatar