npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-safe-html-parser

v1.0.3

Published

A secure, lightweight HTML parser for React with XSS protection and SSR support

Downloads

8

Readme

React Safe HTML Parser

A secure, lightweight HTML parser for React with XSS protection and SSR support. Perfect for Vercel deployments and Next.js applications.

✨ Features

  • Secure by default - XSS protection with configurable sanitization
  • React 18+ compatible - Supports concurrent rendering and modern features
  • SSR/SSG ready - Works seamlessly with Next.js and Vercel
  • TypeScript support - Full type definitions included
  • Custom components - Replace HTML tags with your own React components
  • Performance optimized - Memoized parsing and tree-shakeable
  • Isomorphic - Works in both browser and Node.js environments

🚀 Installation

npm install react-safe-html-parser
# or
yarn add react-safe-html-parser
# or
pnpm add react-safe-html-parser

📦 Peer Dependencies

This library requires React 18+ as a peer dependency:

{
  "peerDependencies": {
    "react": ">=18.0.0",
    "react-dom": ">=18.0.0"
  }
}

🎯 Basic Usage

Simple HTML Parsing

import { HtmlParser } from 'react-safe-html-parser';

function App() {
  const html = '<h1>Hello World</h1><p>This is <strong>bold</strong> text.</p>';
  
  return (
    <div>
      <HtmlParser html={html} />
    </div>
  );
}

With Custom Components

import { HtmlParser } from 'react-safe-html-parser';

const CustomHeading = ({ children, ...props }) => (
  <h1 className="custom-heading" {...props}>
    {children}
  </h1>
);

function App() {
  const html = '<h1>Custom Heading</h1><p>Regular paragraph</p>';
  
  return (
    <HtmlParser 
      html={html}
      options={{
        components: {
          h1: CustomHeading
        }
      }}
    />
  );
}

With Transform Functions

import { HtmlParser } from 'react-safe-html-parser';

function App() {
  const html = '<p>Transform this</p><div>Keep this</div>';
  
  return (
    <HtmlParser 
      html={html}
      options={{
        transform: (node, index) => {
          if (node.tagName === 'p') {
            return React.createElement('h2', {}, 'Transformed!');
          }
          return null; // Return null to skip the node
        }
      }}
    />
  );
}

🔧 Advanced Configuration

Custom Sanitization

import { HtmlParser } from 'react-safe-html-parser';

function App() {
  const html = '<div onclick="alert(1)" style="color: red;">Content</div>';
  
  return (
    <HtmlParser 
      html={html}
      options={{
        sanitize: {
          allowedTags: ['div', 'span', 'p'],
          allowedAttributes: ['class', 'id', 'style'],
          allowedStyles: ['color', 'background-color'],
          removeScripts: true,
          removeComments: true
        }
      }}
    />
  );
}

Disable HTML Entity Decoding

import { HtmlParser } from 'react-safe-html-parser';

function App() {
  const html = '<p>Hello &amp; World &lt;3</p>';
  
  return (
    <HtmlParser 
      html={html}
      options={{
        decodeHtmlEntities: false
      }}
    />
  );
}

Custom Style Parsing

import { HtmlParser } from 'react-safe-html-parser';

function App() {
  const html = '<div style="color: red; font-size: 16px;">Styled content</div>';
  
  return (
    <HtmlParser 
      html={html}
      options={{
        parseStyle: true, // Converts style string to object
        sanitize: {
          allowedStyles: ['color', 'font-size']
        }
      }}
    />
  );
}

🛡️ Security Features

XSS Protection

The library automatically protects against common XSS attacks:

  • Event handlers removed: All on* attributes are stripped
  • Dangerous protocols blocked: javascript:, data:, vbscript: URLs are removed
  • Script tags removed: All <script> tags and content are stripped
  • Form elements removed: <form>, <input>, <button> etc. are removed
  • Configurable allowlists: Control which tags and attributes are allowed

Security Configuration

import { HtmlParser, DEFAULT_SECURITY_CONFIG } from 'react-safe-html-parser';

// Use default security settings
const html = '<div onclick="alert(1)">Content</div>';
<HtmlParser html={html} /> // onclick will be removed

// Custom security settings
<HtmlParser 
  html={html}
  options={{
    sanitize: {
      allowedTags: ['div', 'span'],
      allowedAttributes: ['class'],
      removeScripts: true
    }
  }}
/>

🔄 SSR/SSG Support

Next.js Integration

// pages/index.tsx
import { HtmlParser } from 'react-safe-html-parser';

export default function HomePage() {
  const html = '<h1>Server-side rendered content</h1>';
  
  return (
    <div>
      <HtmlParser html={html} />
    </div>
  );
}

Vercel Deployment

The library works seamlessly with Vercel deployments:

// components/ContentRenderer.tsx
import { HtmlParser } from 'react-safe-html-parser';

interface ContentRendererProps {
  content: string;
}

export function ContentRenderer({ content }: ContentRendererProps) {
  return (
    <HtmlParser 
      html={content}
      fallback={<div>Loading content...</div>}
      showErrors={process.env.NODE_ENV === 'development'}
    />
  );
}

🎨 Styling

Wrapper Styling

import { HtmlParser } from 'react-safe-html-parser';

function App() {
  const html = '<p>Content</p>';
  
  return (
    <HtmlParser 
      html={html}
      className="content-wrapper"
      style={{ 
        padding: '20px',
        backgroundColor: '#f5f5f5'
      }}
    />
  );
}

CSS-in-JS Integration

import styled from 'styled-components';
import { HtmlParser } from 'react-safe-html-parser';

const StyledWrapper = styled.div`
  padding: 20px;
  border: 1px solid #ccc;
  
  h1 {
    color: #333;
    font-size: 24px;
  }
  
  p {
    line-height: 1.6;
  }
`;

function App() {
  const html = '<h1>Title</h1><p>Content</p>';
  
  return (
    <StyledWrapper>
      <HtmlParser html={html} />
    </StyledWrapper>
  );
}

🔧 API Reference

HtmlParser Props

interface HtmlParserProps {
  html: string;                    // HTML string to parse
  options?: ParserOptions;         // Parser configuration
  className?: string;              // CSS class for wrapper
  style?: React.CSSProperties;     // Inline styles for wrapper
  fallback?: ReactNode;           // Content to show if parsing fails
  showErrors?: boolean;           // Whether to log errors to console
}

ParserOptions

interface ParserOptions {
  components?: ComponentMap;        // Custom component replacements
  transform?: TransformFunction;    // Node transformation function
  sanitize?: SanitizeOptions;      // Sanitization settings
  decodeHtmlEntities?: boolean;     // Whether to decode HTML entities
  parseStyle?: boolean;            // Whether to parse style attributes
  entityDecoder?: (entity: string) => string; // Custom entity decoder
}

Utility Functions

import { 
  parseHtmlToReact, 
  parseHtmlToElement,
  sanitizeAttributes,
  sanitizeStyles,
  decodeHtmlEntities
} from 'react-safe-html-parser';

// Parse to multiple elements
const result = parseHtmlToReact('<h1>Title</h1><p>Content</p>');

// Parse to single element (wrapped in Fragment if multiple)
const element = parseHtmlToElement('<div>Content</div>');

// Manual sanitization
const cleanAttrs = sanitizeAttributes({ onclick: 'alert(1)' }, 'div');
const cleanStyles = sanitizeStyles('color: red; font-size: 16px;');
const decoded = decodeHtmlEntities('Hello &amp; World');

🧪 Testing

import { render, screen } from '@testing-library/react';
import { HtmlParser } from 'react-safe-html-parser';

test('renders parsed HTML', () => {
  render(<HtmlParser html="<h1>Test</h1>" />);
  expect(screen.getByRole('heading')).toBeInTheDocument();
});

test('sanitizes dangerous content', () => {
  render(<HtmlParser html="<div onclick='alert(1)'>Content</div>" />);
  const div = screen.getByText('Content');
  expect(div).not.toHaveAttribute('onclick');
});

🚀 Performance

Memoization

The component automatically memoizes parsed output for performance:

import { HtmlParser } from 'react-safe-html-parser';

function App() {
  const html = '<div>Static content</div>';
  
  // This will only parse once, even if the component re-renders
  return <HtmlParser html={html} />;
}

Tree Shaking

The library is fully tree-shakeable. Only import what you need:

// Only import the component
import { HtmlParser } from 'react-safe-html-parser';

// Or import utilities separately
import { parseHtmlToReact } from 'react-safe-html-parser';

🔧 Troubleshooting

Common Issues

1. React 18+ Required

# Make sure you have React 18+ installed
npm install react@^18.0.0 react-dom@^18.0.0

2. SSR Issues

// For Next.js, ensure you're using the component in a client component
'use client';
import { HtmlParser } from 'react-safe-html-parser';

3. TypeScript Errors

// Make sure you have React types installed
npm install --save-dev @types/react @types/react-dom

Debug Mode

Enable error logging in development:

<HtmlParser 
  html={html}
  showErrors={process.env.NODE_ENV === 'development'}
  fallback={<div>Parsing failed</div>}
/>

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📄 License

MIT License - see LICENSE for details.

🙏 Acknowledgments

  • Built with ❤️ for the React community
  • Inspired by the need for secure HTML parsing in modern React applications
  • Designed for seamless Vercel and Next.js integration

Usage

For SSR/PDF/Non-DOM (NO hooks, safe everywhere)

import { parseHtmlToReact, parseHtmlToElement } from 'react-safe-html-parser';

const elements = parseHtmlToReact(htmlString, options); // returns array
const element = parseHtmlToElement(htmlString, options); // returns single element or Fragment

For React DOM (with hooks, memoized)

import { HtmlParser } from 'react-safe-html-parser';

<HtmlParser html={htmlString} options={...} />

For SSR/PDF as a component (no hooks)

import { HtmlParserStatic } from 'react-safe-html-parser';

<HtmlParserStatic html={htmlString} options={...} />

When to use what?

  • SSR/PDF/Node.js: Use parseHtmlToReact or parseHtmlToElement (pure functions, no hooks)
  • React DOM: Use HtmlParser (uses hooks for memoization)
  • React PDF/SSR as a component: Use HtmlParserStatic (no hooks)