npm.io
2.0.0 • Published 6h ago

@naverpay/safe-html-react-parser

Licence
Version
2.0.0
Deps
2
Size
17 kB
Vulns
0
Weekly
168
Stars
115

safe-html-react-parser

A secure wrapper for html-react-parser with DOMPurify that automatically sanitizes HTML before parsing.

What it does

  • Security: Automatically sanitizes malicious HTML using DOMPurify
  • React: Seamlessly integrates with html-react-parser
  • Universal: Works in both browser and Node.js (SSR) environments
  • Custom Tags: Handles project-specific tags like <custom> safely
  • Flexible: Choose your DOM implementation (jsdom, happy-dom, or linkedom)
  • Optimized: Built-in caching and memory management

Installation

npm install @naverpay/safe-html-react-parser
Choosing a DOM Implementation (Server-Side Only)

For server-side rendering, you need to install one of the following DOM implementations:

# Option 1: jsdom (most complete, heavier)
npm install jsdom

# Option 2: happy-dom (faster, lighter, recommended)
npm install happy-dom

# Option 3: linkedom (fastest, lightest)
npm install linkedom

The library will automatically detect and use the first available implementation in this order: jsdom → happy-dom → linkedom.

Basic Usage

import { safeParse } from '@naverpay/safe-html-react-parser'

// Basic usage - automatically sanitizes dangerous HTML
const Component = () => {
  const maliciousHtml = '<p>Hello <script>alert("XSS")</script>World</p>'
  return <div>{safeParse(maliciousHtml)}</div>
}
// Result: <div><p>Hello World</p></div>

API

safeParse(htmlString, options?)

Parses HTML string into React elements with automatic XSS protection.

Parameters
  • htmlString (string): The HTML string to parse
  • options (SafeParseOptions, optional): Configuration options
Options
interface SafeParseOptions extends HTMLReactParserOptions {
  // DOMPurify configuration
  sanitizeConfig?: DOMPurify.Config
  
  // Custom tags to preserve during sanitization
  preserveCustomTags?: string[]
}
Returns

React elements or array of React elements

Advanced Usage

Custom Sanitization Config
import { safeParse } from '@naverpay/safe-html-react-parser'

const html = '<div class="content"><style>body{color:red}</style><p>Text</p></div>'

const result = safeParse(html, {
  sanitizeConfig: {
    ALLOWED_TAGS: ['div', 'p', 'style'], // Allow style tags
    ALLOWED_ATTR: ['class'],
    ALLOW_ARIA_ATTR: true
  }
})
Preserving Custom Tags

Use preserveCustomTags to preserve project-specific tags that would otherwise be removed:

import { safeParse } from '@naverpay/safe-html-react-parser'

// Preserve custom tags like <g>, <path>, etc.
const svgContent = '<g><path d="M10,10 L20,20"/></g>'

const result = safeParse(svgContent, {
  preserveCustomTags: ['g', 'path'],
  replace: (domNode) => {
    if (domNode.name === 'g') {
      return <g {...domNode.attribs}>{/* custom rendering */}</g>
    }
    if (domNode.name === 'path') {
      return <path {...domNode.attribs} />
    }
  }
})
Using with html-react-parser Options

All html-react-parser options are supported:

import { safeParse } from '@naverpay/safe-html-react-parser'

const html = '<div id="content"><p>Hello</p><img src="image.jpg" alt="test"/></div>'

const result = safeParse(html, {
  replace: (domNode) => {
    if (domNode.name === 'img') {
      return <img {...domNode.attribs} loading="lazy" />
    }
  },
  trim: true
})
Configuring DOM Implementation (Server-Side)

You have two ways to configure the DOM implementation:

Pass domPurifyOptions directly to safeParse():

import { safeParse } from '@naverpay/safe-html-react-parser'
import { Window } from 'happy-dom'

const result = safeParse(htmlString, {
  domPurifyOptions: {
    domWindowFactory: () => new Window(),
    enableCache: true,
    maxCacheSize: 100
  }
})
Method 2: Global configuration

Configure once at app initialization:

import { configureDOMPurify } from '@naverpay/safe-html-react-parser'

// Using jsdom
import { JSDOM } from 'jsdom'
configureDOMPurify({
  domWindowFactory: () => new JSDOM('<!DOCTYPE html>'),
  enableCache: true,
  maxCacheSize: 100,
  recreateInterval: 1000 // Recreate DOM instance every 1000 sanitizations
})

// Using happy-dom (recommended for better performance)
import { Window } from 'happy-dom'
configureDOMPurify({
  domWindowFactory: () => new Window(),
  enableCache: true,
  recreateInterval: 500
})

// Using linkedom (fastest, minimal footprint)
import { parseHTML } from 'linkedom'
configureDOMPurify({
  domWindowFactory: () => parseHTML('<!DOCTYPE html>'),
  enableCache: true
})

If you don't configure anything, the library will automatically try jsdom → happy-dom → linkedom in that order.

Default Allowed Tags

By default, the following HTML tags are allowed:

ALLOWED_TAGS: [
  'p', 'br', 'strong', 'em', 'b', 'i', 'u', 'span', 'div',
  'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h',
  'ul', 'ol', 'li', 'dl', 'dt', 'dd',
  'a', 'img'
]

Performance Optimization

Caching

By default, caching is enabled to improve performance:

configureDOMPurify({
  enableCache: true,      // Default: true
  maxCacheSize: 100,      // Default: 100
})
Memory Management

The DOM instance is automatically recreated periodically to prevent memory leaks:

configureDOMPurify({
  recreateInterval: 1000  // Default: 1000 sanitization calls
})
DOM Implementation Comparison
Implementation Speed Memory Completeness Recommended For
jsdom Slower Higher Most complete Maximum compatibility
happy-dom Fast Medium Good Balanced (Recommended)
linkedom Fastest Lowest Basic Performance-critical apps

Security Notes

  • All HTML is sanitized by DOMPurify before parsing
  • Dangerous tags like <script>, <iframe>, <object> are automatically removed
  • Event handlers like onclick, onload are stripped out
  • Only safe attributes are preserved by default

Built with

License

MIT

Keywords