CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-html-react-parser

HTML to React parser that works on both server-side and client-side environments

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

HTML React Parser

HTML React Parser is a robust TypeScript library that converts HTML strings into React elements. It works seamlessly in both server-side (Node.js) and client-side (browser) environments, providing comprehensive HTML parsing with advanced customization options.

Package Information

  • Package Name: html-react-parser
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install html-react-parser

Core Imports

import parse from "html-react-parser";
import type { HTMLReactParserOptions } from "html-react-parser";

For additional utilities:

import { 
  attributesToProps, 
  domToReact, 
  htmlToDOM,
  Element,
  Text,
  Comment
} from "html-react-parser";

CommonJS:

const parse = require("html-react-parser").default;
const { attributesToProps, domToReact } = require("html-react-parser");

UMD (CDN):

<!-- HTMLReactParser depends on React -->
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/html-react-parser@latest/dist/html-react-parser.min.js"></script>
<script>
  // Available as window.HTMLReactParser
  const parsed = window.HTMLReactParser('<p>Hello from CDN!</p>');
</script>

Basic Usage

import parse from "html-react-parser";

// Simple HTML parsing
const element = parse('<p>Hello, World!</p>');
// Returns: React.createElement('p', {}, 'Hello, World!')

// Complex HTML with nested elements
const complexHtml = `
  <div class="container">
    <h1>Title</h1>
    <p style="color: red;">Red text</p>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
    </ul>
  </div>
`;
const result = parse(complexHtml);

// With options
const customParsed = parse('<div data-id="123">Content</div>', {
  replace: (domNode) => {
    if (domNode.type === 'tag' && domNode.name === 'div') {
      return <span>Replaced content</span>;
    }
  }
});

Architecture

HTML React Parser is built around several key components:

  • Main Parser: Core HTMLReactParser function that orchestrates the conversion process
  • DOM Processing: htmlToDOM converts HTML strings to DOM nodes using html-dom-parser
  • React Conversion: domToReact transforms DOM nodes into React elements
  • Attribute Handling: attributesToProps converts HTML attributes to React props with proper naming
  • Customization System: Options interface allowing element replacement, transformation, and custom libraries
  • Type Safety: Full TypeScript integration with comprehensive type definitions

Capabilities

HTML Parsing

Core functionality for converting HTML strings to React elements with comprehensive options support.

/**
 * Converts HTML string to React elements.
 * @param html - HTML string to parse
 * @param options - Optional parser configuration
 * @returns React element(s), empty array, or string
 * @throws TypeError if first argument is not a string
 */
function HTMLReactParser(
  html: string,
  options?: HTMLReactParserOptions
): string | JSX.Element | JSX.Element[];

Usage Examples:

import parse from "html-react-parser";

// Basic parsing
parse('<p>Hello</p>'); // React element
parse('Just text'); // String
parse(''); // Empty array []

// Multiple elements
parse('<p>First</p><p>Second</p>'); // Array of React elements

// Self-closing tags
parse('<img src="image.jpg" alt="Photo" />'); // React element with props

// Nested elements with attributes
parse(`
  <div className="wrapper" data-testid="container">
    <h1 style="font-size: 24px;">Title</h1>
    <button onClick="handleClick()">Click me</button>
  </div>
`);

DOM to React Conversion

Low-level function for converting DOM nodes directly to React elements.

/**
 * Converts DOM nodes to JSX element(s).
 * @param nodes - Array of DOM nodes to convert
 * @param options - Parser configuration with default empty object
 * @returns String or JSX element(s)
 */
function domToReact(
  nodes: DOMNode[],
  options: HTMLReactParserOptions = {}
): string | JSX.Element | JSX.Element[];

HTML to DOM Parsing

Utility function that converts HTML strings to DOM node structures.

/**
 * Converts HTML string to DOM nodes using html-dom-parser
 * @param html - HTML string to parse
 * @param options - htmlparser2 parsing options
 * @returns Array of DOM nodes
 */
function htmlToDOM(html: string, options?: any): DOMNode[];

Attribute Processing

Converts HTML/SVG DOM attributes to React-compatible props with proper naming conventions.

/**
 * Converts HTML/SVG DOM attributes to React props.
 * @param attributes - HTML/SVG DOM attributes object
 * @param nodeName - DOM node name for context-specific processing
 * @returns React props object
 */
function attributesToProps(
  attributes?: Attributes,
  nodeName?: string
): Props;

type Attributes = Record<PropertyKey, string>;

interface Props extends Record<PropertyKey, string | boolean> {
  dangerouslySetInnerHTML?: {
    __html: string;
  };
  key?: string | number;
  style?: Record<PropertyKey, string>;
}

Usage Examples:

import { attributesToProps } from "html-react-parser";

// HTML attributes to React props
const htmlAttrs = { 'class': 'btn', 'data-id': '123', 'for': 'input1' };
const reactProps = attributesToProps(htmlAttrs);
// Result: { className: 'btn', 'data-id': '123', htmlFor: 'input1' }

// Input element handling (controlled vs uncontrolled)
const inputAttrs = { type: 'text', value: 'hello' };
const inputProps = attributesToProps(inputAttrs, 'input');
// Result: { type: 'text', defaultValue: 'hello' } // Converts to uncontrolled

// Style attribute processing
const styledAttrs = { style: 'color: red; font-size: 16px;' };
const styledProps = attributesToProps(styledAttrs);
// Result: { style: { color: 'red', fontSize: '16px' } }

Element Replacement

Advanced customization through the replace option for targeted element modification.

type ReplaceFunction = (
  domNode: DOMNode,
  index: number
) => JSX.Element | string | null | boolean | object | void;

Usage Examples:

import parse from "html-react-parser";

// Replace specific elements
const html = '<p>Text</p><button>Click</button>';
const result = parse(html, {
  replace: (domNode) => {
    if (domNode.type === 'tag' && domNode.name === 'button') {
      return <button className="custom-btn">{domNode.children[0].data}</button>;
    }
  }
});

// Conditional element replacement
parse('<div class="old">Content</div>', {
  replace: (domNode) => {
    if (domNode.type === 'tag' && domNode.attribs?.class === 'old') {
      return <div className="new">Updated content</div>;
    }
  }
});

// Remove elements by returning null
parse('<script>alert("xss")</script><p>Safe content</p>', {
  replace: (domNode) => {
    if (domNode.type === 'tag' && domNode.name === 'script') {
      return null; // Remove script tags
    }
  }
});

Transform Function

Post-processing transformation of React nodes after initial creation.

type TransformFunction = (
  reactNode: ReactNode,
  domNode: DOMNode,
  index: number
) => JSX.Element | string | null | void;

Usage Examples:

import parse from "html-react-parser";
import React from "react";

// Add props to all elements
parse('<div><p>Text</p></div>', {
  transform: (reactNode, domNode, index) => {
    if (reactNode.type) {
      return React.cloneElement(reactNode, {
        ...reactNode.props,
        'data-index': index
      });
    }
    return reactNode;
  }
});

// Wrap text nodes
parse('<p>Hello world</p>', {
  transform: (reactNode, domNode) => {
    if (typeof reactNode === 'string') {
      return <span className="text-wrapper">{reactNode}</span>;
    }
    return reactNode;
  }
});

Custom Library Support

Integration with alternative React-compatible libraries like Preact.

interface LibraryConfig {
  cloneElement: (
    element: JSX.Element,
    props?: object,
    ...children: any[]
  ) => JSX.Element;
  createElement: (
    type: any,
    props?: object,
    ...children: any[]
  ) => JSX.Element;
  isValidElement: (element: any) => boolean;
  [key: string]: any;
}

Usage Examples:

import { h, cloneElement, isValidElement } from "preact";
import parse from "html-react-parser";

// Use with Preact
const preactResult = parse('<div>Hello Preact</div>', {
  library: {
    createElement: h,
    cloneElement: cloneElement,
    isValidElement: isValidElement
  }
});

Configuration Options

interface HTMLReactParserOptions {
  /** htmlparser2 and domhandler configuration options */
  htmlparser2?: ParserOptions & DomHandlerOptions;
  
  /** Custom React-compatible library methods */
  library?: LibraryConfig;
  
  /** Function to replace DOM elements with custom React elements */
  replace?: ReplaceFunction;
  
  /** Function to transform React nodes after creation */
  transform?: TransformFunction;
  
  /** Whether to trim whitespace text nodes */
  trim?: boolean;
}

DOM Node Types

Re-exported DOM node classes from the domhandler library for type checking and instanceof operations.

/**
 * DOM element node class
 */
class Element {
  type: 'tag' | 'script' | 'style';
  name: string;
  attribs: Record<string, string>;
  children: DOMNode[];
  parent?: DOMNode;
}

/**
 * DOM text node class
 */
class Text {
  type: 'text';
  data: string;
  parent?: DOMNode;
}

/**
 * DOM comment node class
 */
class Comment {
  type: 'comment';
  data: string;
  parent?: DOMNode;
}

/**
 * DOM processing instruction node class
 */
class ProcessingInstruction {
  type: 'directive';
  name: string;
  data: string;
  parent?: DOMNode;
}

/**
 * Union type for all DOM node types
 */
type DOMNode = Element | Text | Comment | ProcessingInstruction;

Usage Examples:

import parse, { Element, Text } from "html-react-parser";

parse('<div>Hello</div>', {
  replace: (domNode) => {
    if (domNode instanceof Element && domNode.name === 'div') {
      return <section>{domNode.children}</section>;
    }
    if (domNode instanceof Text && domNode.data.includes('Hello')) {
      return <strong>{domNode.data}</strong>;
    }
  }
});

Advanced Configuration

htmlparser2 Options

Fine-tune the underlying HTML parsing behavior through htmlparser2 configuration.

⚠️ Warning: htmlparser2 options only work on the server-side (Node.js) and do not work on the client-side (browser). Using these options can break universal rendering.

interface ParserOptions {
  /** Decode HTML entities in attribute values and text content */
  decodeEntities?: boolean;
  /** Convert tag names to lowercase */
  lowerCaseTags?: boolean;
  /** Convert attribute names to lowercase */
  lowerCaseAttributeNames?: boolean;
  /** Recognize self-closing tags */
  recognizeSelfClosing?: boolean;
  /** Enable XML mode with stricter parsing rules */
  xmlMode?: boolean;
  /** Additional htmlparser2 configuration options */
  [key: string]: any;
}

Usage Examples:

import parse from "html-react-parser";

// Custom parsing options
parse('<DIV CLASS="Test">Content</DIV>', {
  htmlparser2: {
    lowerCaseTags: false,
    lowerCaseAttributeNames: false
  }
});

// Handle XML-style self-closing tags
parse('<custom-element attr="value"/>', {
  htmlparser2: {
    recognizeSelfClosing: true
  }
});

Error Handling

The parser throws specific errors for invalid inputs and provides helpful error messages.

import parse from "html-react-parser";

// TypeError for non-string inputs
try {
  parse(null as any); // TypeError: First argument must be a string
  parse(123 as any);  // TypeError: First argument must be a string
  parse({} as any);   // TypeError: First argument must be a string
} catch (error) {
  console.error(error.message); // "First argument must be a string"
}

// Empty strings return empty arrays (not errors)
const empty = parse(''); // []

// Invalid HTML is parsed as best as possible (no errors thrown)
const malformed = parse('<div><p>Unclosed div'); // Still produces React elements
const selfClosing = parse('<div/>'); // Parsed correctly
const mismatched = parse('<div></span>'); // Best-effort parsing

// Browser/server compatibility errors
try {
  parse('<div>content</div>', {
    htmlparser2: {
      xmlMode: true // This works on server but may cause issues on client
    }
  });
} catch (error) {
  // Handle potential universal rendering issues
  console.warn('htmlparser2 options may not work on client-side');
}
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/html-react-parser@5.2.x
Publish Source
CLI
Badge
tessl/npm-html-react-parser badge