Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@banzai-inc/html-to-react

banzai-inc447MIT1.3.8

A lightweight library that converts raw HTML to a React DOM structure.

react, react-component, html

readme

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 = htmlToReactParser.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

changelog

Change Log

v1.3.4

  • Use lodash.camelcase instead of underscore.string.fp #76 (codepunkt)

v1.3.3

  • Handle free-standing text nodes in HTML

Full Changelog

v1.3.2

  • Handle directives in HTML

Full Changelog

v1.3.1

  • Handle invalid inline styles

Full Changelog

Merged pull requests:

v1.3.0

  • Upgrade to React 16

Full Changelog

v1.2.12

  • Trim inline style props values

Full Changelog

Merged pull requests:

v1.2.11

  • Handle base64 inlined images

Full Changelog

Merged pull requests:

v1.2.10

  • Handle background-image styles

Full Changelog

Merged pull requests:

v1.2.9

  • Handle for attribute

Full Changelog

v1.2.8

  • Handle xmlns:xlink

Full Changelog

Merged pull requests:

v1.2.7

  • Depend directly on domhandler, for compatibility with older Node.js

Full Changelog

v1.2.6

  • Make library smaller

Full Changelog

v1.2.5

Full Changelog

Merged pull requests:

  • Test of inline style with characters entities. #21 (Gycianka)

v1.2.4

Full Changelog

Merged pull requests:

  • parsing multiple root elements #17 (oroce)

v1.2.3

Full Changelog

Merged pull requests:

  • Occurrence of ampersand in attributes are decoded to & to avoid ano… #15 (gerhardsletten)

v1.2.2

Full Changelog

Merged pull requests:

  • handle xmlns attributes (e.g. xlink:href) #9 (gfx)

v1.2.1

Full Changelog

v1.2.0

Full Changelog

Merged pull requests:

v1.1.2

Full Changelog

v1.1.1

Full Changelog

v1.1.0

Full Changelog

v1.0.0

Full Changelog

Fixed bugs:

  • Travis build fails due to a ReferenceError #11

Closed issues:

  • Should not insert spans into tables even if there is white space #30
  • Img, br and hr tags produce warnings #29
  • using import instead of require #26
  • Cherry pick lodash #22
  • problem with textarea #9
  • Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method #7
  • State of the library? #6
  • best way to pass callbacks? #5

Merged pull requests:

v0.1.0 (2015-06-20)

Full Changelog

v0.0.6 (2015-06-20)

Full Changelog

v0.0.5 (2015-06-20)

Full Changelog

v0.0.4 (2015-06-20)

Full Changelog

v0.0.3 (2015-06-20)

Full Changelog

v0.0.2 (2015-06-20)

* This Change Log was automatically generated by github_changelog_generator