HTML to React parser that works on both server-side and client-side environments
npx @tessl/cli install tessl/npm-html-react-parser@5.2.00
# HTML React Parser
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: html-react-parser
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install html-react-parser`
10
11
## Core Imports
12
13
```typescript
14
import parse from "html-react-parser";
15
import type { HTMLReactParserOptions } from "html-react-parser";
16
```
17
18
For additional utilities:
19
20
```typescript
21
import {
22
attributesToProps,
23
domToReact,
24
htmlToDOM,
25
Element,
26
Text,
27
Comment
28
} from "html-react-parser";
29
```
30
31
CommonJS:
32
33
```javascript
34
const parse = require("html-react-parser").default;
35
const { attributesToProps, domToReact } = require("html-react-parser");
36
```
37
38
UMD (CDN):
39
40
```html
41
<!-- HTMLReactParser depends on React -->
42
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
43
<script src="https://unpkg.com/html-react-parser@latest/dist/html-react-parser.min.js"></script>
44
<script>
45
// Available as window.HTMLReactParser
46
const parsed = window.HTMLReactParser('<p>Hello from CDN!</p>');
47
</script>
48
```
49
50
## Basic Usage
51
52
```typescript
53
import parse from "html-react-parser";
54
55
// Simple HTML parsing
56
const element = parse('<p>Hello, World!</p>');
57
// Returns: React.createElement('p', {}, 'Hello, World!')
58
59
// Complex HTML with nested elements
60
const complexHtml = `
61
<div class="container">
62
<h1>Title</h1>
63
<p style="color: red;">Red text</p>
64
<ul>
65
<li>Item 1</li>
66
<li>Item 2</li>
67
</ul>
68
</div>
69
`;
70
const result = parse(complexHtml);
71
72
// With options
73
const customParsed = parse('<div data-id="123">Content</div>', {
74
replace: (domNode) => {
75
if (domNode.type === 'tag' && domNode.name === 'div') {
76
return <span>Replaced content</span>;
77
}
78
}
79
});
80
```
81
82
## Architecture
83
84
HTML React Parser is built around several key components:
85
86
- **Main Parser**: Core `HTMLReactParser` function that orchestrates the conversion process
87
- **DOM Processing**: `htmlToDOM` converts HTML strings to DOM nodes using html-dom-parser
88
- **React Conversion**: `domToReact` transforms DOM nodes into React elements
89
- **Attribute Handling**: `attributesToProps` converts HTML attributes to React props with proper naming
90
- **Customization System**: Options interface allowing element replacement, transformation, and custom libraries
91
- **Type Safety**: Full TypeScript integration with comprehensive type definitions
92
93
## Capabilities
94
95
### HTML Parsing
96
97
Core functionality for converting HTML strings to React elements with comprehensive options support.
98
99
```typescript { .api }
100
/**
101
* Converts HTML string to React elements.
102
* @param html - HTML string to parse
103
* @param options - Optional parser configuration
104
* @returns React element(s), empty array, or string
105
* @throws TypeError if first argument is not a string
106
*/
107
function HTMLReactParser(
108
html: string,
109
options?: HTMLReactParserOptions
110
): string | JSX.Element | JSX.Element[];
111
```
112
113
**Usage Examples:**
114
115
```typescript
116
import parse from "html-react-parser";
117
118
// Basic parsing
119
parse('<p>Hello</p>'); // React element
120
parse('Just text'); // String
121
parse(''); // Empty array []
122
123
// Multiple elements
124
parse('<p>First</p><p>Second</p>'); // Array of React elements
125
126
// Self-closing tags
127
parse('<img src="image.jpg" alt="Photo" />'); // React element with props
128
129
// Nested elements with attributes
130
parse(`
131
<div className="wrapper" data-testid="container">
132
<h1 style="font-size: 24px;">Title</h1>
133
<button onClick="handleClick()">Click me</button>
134
</div>
135
`);
136
```
137
138
### DOM to React Conversion
139
140
Low-level function for converting DOM nodes directly to React elements.
141
142
```typescript { .api }
143
/**
144
* Converts DOM nodes to JSX element(s).
145
* @param nodes - Array of DOM nodes to convert
146
* @param options - Parser configuration with default empty object
147
* @returns String or JSX element(s)
148
*/
149
function domToReact(
150
nodes: DOMNode[],
151
options: HTMLReactParserOptions = {}
152
): string | JSX.Element | JSX.Element[];
153
```
154
155
### HTML to DOM Parsing
156
157
Utility function that converts HTML strings to DOM node structures.
158
159
```typescript { .api }
160
/**
161
* Converts HTML string to DOM nodes using html-dom-parser
162
* @param html - HTML string to parse
163
* @param options - htmlparser2 parsing options
164
* @returns Array of DOM nodes
165
*/
166
function htmlToDOM(html: string, options?: any): DOMNode[];
167
```
168
169
### Attribute Processing
170
171
Converts HTML/SVG DOM attributes to React-compatible props with proper naming conventions.
172
173
```typescript { .api }
174
/**
175
* Converts HTML/SVG DOM attributes to React props.
176
* @param attributes - HTML/SVG DOM attributes object
177
* @param nodeName - DOM node name for context-specific processing
178
* @returns React props object
179
*/
180
function attributesToProps(
181
attributes?: Attributes,
182
nodeName?: string
183
): Props;
184
185
type Attributes = Record<PropertyKey, string>;
186
187
interface Props extends Record<PropertyKey, string | boolean> {
188
dangerouslySetInnerHTML?: {
189
__html: string;
190
};
191
key?: string | number;
192
style?: Record<PropertyKey, string>;
193
}
194
```
195
196
**Usage Examples:**
197
198
```typescript
199
import { attributesToProps } from "html-react-parser";
200
201
// HTML attributes to React props
202
const htmlAttrs = { 'class': 'btn', 'data-id': '123', 'for': 'input1' };
203
const reactProps = attributesToProps(htmlAttrs);
204
// Result: { className: 'btn', 'data-id': '123', htmlFor: 'input1' }
205
206
// Input element handling (controlled vs uncontrolled)
207
const inputAttrs = { type: 'text', value: 'hello' };
208
const inputProps = attributesToProps(inputAttrs, 'input');
209
// Result: { type: 'text', defaultValue: 'hello' } // Converts to uncontrolled
210
211
// Style attribute processing
212
const styledAttrs = { style: 'color: red; font-size: 16px;' };
213
const styledProps = attributesToProps(styledAttrs);
214
// Result: { style: { color: 'red', fontSize: '16px' } }
215
```
216
217
### Element Replacement
218
219
Advanced customization through the replace option for targeted element modification.
220
221
```typescript { .api }
222
type ReplaceFunction = (
223
domNode: DOMNode,
224
index: number
225
) => JSX.Element | string | null | boolean | object | void;
226
```
227
228
**Usage Examples:**
229
230
```typescript
231
import parse from "html-react-parser";
232
233
// Replace specific elements
234
const html = '<p>Text</p><button>Click</button>';
235
const result = parse(html, {
236
replace: (domNode) => {
237
if (domNode.type === 'tag' && domNode.name === 'button') {
238
return <button className="custom-btn">{domNode.children[0].data}</button>;
239
}
240
}
241
});
242
243
// Conditional element replacement
244
parse('<div class="old">Content</div>', {
245
replace: (domNode) => {
246
if (domNode.type === 'tag' && domNode.attribs?.class === 'old') {
247
return <div className="new">Updated content</div>;
248
}
249
}
250
});
251
252
// Remove elements by returning null
253
parse('<script>alert("xss")</script><p>Safe content</p>', {
254
replace: (domNode) => {
255
if (domNode.type === 'tag' && domNode.name === 'script') {
256
return null; // Remove script tags
257
}
258
}
259
});
260
```
261
262
### Transform Function
263
264
Post-processing transformation of React nodes after initial creation.
265
266
```typescript { .api }
267
type TransformFunction = (
268
reactNode: ReactNode,
269
domNode: DOMNode,
270
index: number
271
) => JSX.Element | string | null | void;
272
```
273
274
**Usage Examples:**
275
276
```typescript
277
import parse from "html-react-parser";
278
import React from "react";
279
280
// Add props to all elements
281
parse('<div><p>Text</p></div>', {
282
transform: (reactNode, domNode, index) => {
283
if (reactNode.type) {
284
return React.cloneElement(reactNode, {
285
...reactNode.props,
286
'data-index': index
287
});
288
}
289
return reactNode;
290
}
291
});
292
293
// Wrap text nodes
294
parse('<p>Hello world</p>', {
295
transform: (reactNode, domNode) => {
296
if (typeof reactNode === 'string') {
297
return <span className="text-wrapper">{reactNode}</span>;
298
}
299
return reactNode;
300
}
301
});
302
```
303
304
### Custom Library Support
305
306
Integration with alternative React-compatible libraries like Preact.
307
308
```typescript { .api }
309
interface LibraryConfig {
310
cloneElement: (
311
element: JSX.Element,
312
props?: object,
313
...children: any[]
314
) => JSX.Element;
315
createElement: (
316
type: any,
317
props?: object,
318
...children: any[]
319
) => JSX.Element;
320
isValidElement: (element: any) => boolean;
321
[key: string]: any;
322
}
323
```
324
325
**Usage Examples:**
326
327
```typescript
328
import { h, cloneElement, isValidElement } from "preact";
329
import parse from "html-react-parser";
330
331
// Use with Preact
332
const preactResult = parse('<div>Hello Preact</div>', {
333
library: {
334
createElement: h,
335
cloneElement: cloneElement,
336
isValidElement: isValidElement
337
}
338
});
339
```
340
341
## Configuration Options
342
343
```typescript { .api }
344
interface HTMLReactParserOptions {
345
/** htmlparser2 and domhandler configuration options */
346
htmlparser2?: ParserOptions & DomHandlerOptions;
347
348
/** Custom React-compatible library methods */
349
library?: LibraryConfig;
350
351
/** Function to replace DOM elements with custom React elements */
352
replace?: ReplaceFunction;
353
354
/** Function to transform React nodes after creation */
355
transform?: TransformFunction;
356
357
/** Whether to trim whitespace text nodes */
358
trim?: boolean;
359
}
360
```
361
362
## DOM Node Types
363
364
Re-exported DOM node classes from the domhandler library for type checking and instanceof operations.
365
366
```typescript { .api }
367
/**
368
* DOM element node class
369
*/
370
class Element {
371
type: 'tag' | 'script' | 'style';
372
name: string;
373
attribs: Record<string, string>;
374
children: DOMNode[];
375
parent?: DOMNode;
376
}
377
378
/**
379
* DOM text node class
380
*/
381
class Text {
382
type: 'text';
383
data: string;
384
parent?: DOMNode;
385
}
386
387
/**
388
* DOM comment node class
389
*/
390
class Comment {
391
type: 'comment';
392
data: string;
393
parent?: DOMNode;
394
}
395
396
/**
397
* DOM processing instruction node class
398
*/
399
class ProcessingInstruction {
400
type: 'directive';
401
name: string;
402
data: string;
403
parent?: DOMNode;
404
}
405
406
/**
407
* Union type for all DOM node types
408
*/
409
type DOMNode = Element | Text | Comment | ProcessingInstruction;
410
```
411
412
**Usage Examples:**
413
414
```typescript
415
import parse, { Element, Text } from "html-react-parser";
416
417
parse('<div>Hello</div>', {
418
replace: (domNode) => {
419
if (domNode instanceof Element && domNode.name === 'div') {
420
return <section>{domNode.children}</section>;
421
}
422
if (domNode instanceof Text && domNode.data.includes('Hello')) {
423
return <strong>{domNode.data}</strong>;
424
}
425
}
426
});
427
```
428
429
## Advanced Configuration
430
431
### htmlparser2 Options
432
433
Fine-tune the underlying HTML parsing behavior through htmlparser2 configuration.
434
435
> **⚠️ 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.
436
437
```typescript { .api }
438
interface ParserOptions {
439
/** Decode HTML entities in attribute values and text content */
440
decodeEntities?: boolean;
441
/** Convert tag names to lowercase */
442
lowerCaseTags?: boolean;
443
/** Convert attribute names to lowercase */
444
lowerCaseAttributeNames?: boolean;
445
/** Recognize self-closing tags */
446
recognizeSelfClosing?: boolean;
447
/** Enable XML mode with stricter parsing rules */
448
xmlMode?: boolean;
449
/** Additional htmlparser2 configuration options */
450
[key: string]: any;
451
}
452
```
453
454
**Usage Examples:**
455
456
```typescript
457
import parse from "html-react-parser";
458
459
// Custom parsing options
460
parse('<DIV CLASS="Test">Content</DIV>', {
461
htmlparser2: {
462
lowerCaseTags: false,
463
lowerCaseAttributeNames: false
464
}
465
});
466
467
// Handle XML-style self-closing tags
468
parse('<custom-element attr="value"/>', {
469
htmlparser2: {
470
recognizeSelfClosing: true
471
}
472
});
473
```
474
475
### Error Handling
476
477
The parser throws specific errors for invalid inputs and provides helpful error messages.
478
479
```typescript
480
import parse from "html-react-parser";
481
482
// TypeError for non-string inputs
483
try {
484
parse(null as any); // TypeError: First argument must be a string
485
parse(123 as any); // TypeError: First argument must be a string
486
parse({} as any); // TypeError: First argument must be a string
487
} catch (error) {
488
console.error(error.message); // "First argument must be a string"
489
}
490
491
// Empty strings return empty arrays (not errors)
492
const empty = parse(''); // []
493
494
// Invalid HTML is parsed as best as possible (no errors thrown)
495
const malformed = parse('<div><p>Unclosed div'); // Still produces React elements
496
const selfClosing = parse('<div/>'); // Parsed correctly
497
const mismatched = parse('<div></span>'); // Best-effort parsing
498
499
// Browser/server compatibility errors
500
try {
501
parse('<div>content</div>', {
502
htmlparser2: {
503
xmlMode: true // This works on server but may cause issues on client
504
}
505
});
506
} catch (error) {
507
// Handle potential universal rendering issues
508
console.warn('htmlparser2 options may not work on client-side');
509
}
510
```