remark plugin to compile Markdown to HTML
npx @tessl/cli install tessl/npm-remark-html@16.0.00
# remark-html
1
2
remark-html is a unified (remark) plugin that compiles Markdown to HTML. It provides a shortcut for converting markdown documents into sanitized HTML output, serving as an alternative to using the full remark-rehype-rehype-stringify pipeline.
3
4
## Package Information
5
6
- **Package Name**: remark-html
7
- **Package Type**: npm
8
- **Language**: JavaScript with TypeScript definitions
9
- **Installation**: `npm install remark-html`
10
11
## Core Imports
12
13
```javascript
14
import remarkHtml from 'remark-html';
15
```
16
17
For CommonJS:
18
19
```javascript
20
const remarkHtml = require('remark-html');
21
```
22
23
With TypeScript types:
24
25
```typescript
26
import remarkHtml from 'remark-html';
27
import type { Options } from 'remark-html';
28
```
29
30
For advanced type usage:
31
32
```typescript
33
import type { Schema } from 'hast-util-sanitize';
34
import type { Handlers } from 'mdast-util-to-hast';
35
import type { Root } from 'mdast';
36
```
37
38
## Basic Usage
39
40
```javascript
41
import remarkHtml from 'remark-html';
42
import remarkParse from 'remark-parse';
43
import { unified } from 'unified';
44
45
// Basic usage with default sanitization
46
const file = await unified()
47
.use(remarkParse)
48
.use(remarkHtml)
49
.process('# Hello\n\n**World**');
50
51
console.log(String(file));
52
// Output: <h1>Hello</h1>\n<p><strong>World</strong></p>\n
53
```
54
55
## Architecture
56
57
remark-html works within the unified ecosystem by:
58
59
- **Plugin Integration**: Functions as a unified plugin that can be added to any remark processor
60
- **Markdown to HTML Pipeline**: Converts mdast (markdown AST) directly to HTML without exposing intermediate hast (HTML AST)
61
- **Built-in Sanitization**: Uses hast-util-sanitize by default to prevent XSS attacks
62
- **Compiler Pattern**: Sets a compiler function on the unified processor to handle the final output transformation
63
64
## Capabilities
65
66
### HTML Compilation
67
68
Compiles markdown to HTML with built-in sanitization.
69
70
```typescript { .api }
71
/**
72
* Add support for serializing to HTML.
73
*
74
* @param options - Configuration options (optional)
75
* @returns Nothing (modifies processor)
76
*/
77
declare const remarkHtml: Plugin<
78
[(Readonly<Options> | null | undefined)?],
79
Root,
80
string
81
>;
82
83
interface Options {
84
/** How to turn mdast nodes into hast nodes */
85
handlers?: Readonly<Handlers> | null | undefined;
86
/** Sanitize the output, and how (default: true) */
87
sanitize?: Readonly<Schema> | boolean | null | undefined;
88
/** Control dangerous HTML elements */
89
allowDangerousHtml?: boolean | null | undefined;
90
/** Close self-closing elements */
91
closeSelfClosing?: boolean | null | undefined;
92
/** Omit optional closing tags */
93
omitOptionalTags?: boolean | null | undefined;
94
/** Character reference options */
95
characterReferences?: {
96
useShortestReferences?: boolean;
97
omitOptionalSemicolons?: boolean;
98
} | null | undefined;
99
/** Additional options from hast-util-to-html */
100
[key: string]: any;
101
}
102
```
103
104
**Usage Examples:**
105
106
```javascript
107
// Default usage with sanitization
108
const processor = unified()
109
.use(remarkParse)
110
.use(remarkHtml);
111
112
// Disable sanitization (DANGEROUS - allows XSS)
113
const unsafeProcessor = unified()
114
.use(remarkParse)
115
.use(remarkHtml, { sanitize: false });
116
117
// Custom sanitization schema
118
const customProcessor = unified()
119
.use(remarkParse)
120
.use(remarkHtml, {
121
sanitize: { tagNames: ['p', 'strong', 'em', 'a'] }
122
});
123
124
// Custom handlers for mdast to hast conversion
125
const handlerProcessor = unified()
126
.use(remarkParse)
127
.use(remarkHtml, {
128
handlers: {
129
paragraph(state, node) {
130
// Custom paragraph handling
131
return {
132
type: 'element',
133
tagName: 'div',
134
properties: { className: ['custom-paragraph'] },
135
children: state.all(node)
136
};
137
}
138
}
139
});
140
```
141
142
### Configuration Options
143
144
#### Sanitization Control
145
146
Controls HTML sanitization to prevent XSS attacks.
147
148
```typescript { .api }
149
/** Sanitization options */
150
sanitize?: Readonly<Schema> | boolean | null | undefined;
151
```
152
153
- `true` (default): Uses safe default schema from hast-util-sanitize
154
- `false`: **DANGEROUS** - Disables sanitization, allows arbitrary HTML
155
- `Schema`: Custom sanitization schema object
156
157
**Examples:**
158
159
```javascript
160
// Safe default (recommended)
161
.use(remarkHtml, { sanitize: true })
162
163
// Disable sanitization (dangerous)
164
.use(remarkHtml, { sanitize: false })
165
166
// Custom schema allowing only specific tags
167
.use(remarkHtml, {
168
sanitize: {
169
tagNames: ['p', 'strong', 'em', 'a', 'ul', 'ol', 'li'],
170
attributes: {
171
a: ['href'],
172
'*': ['className']
173
}
174
}
175
})
176
```
177
178
#### Custom Handlers
179
180
Customize how specific markdown nodes are converted to HTML.
181
182
```typescript { .api }
183
/** Custom node handlers */
184
handlers?: Readonly<Handlers> | null | undefined;
185
```
186
187
**Example:**
188
189
```javascript
190
.use(remarkHtml, {
191
handlers: {
192
// Custom link handler
193
link(state, node) {
194
return {
195
type: 'element',
196
tagName: 'a',
197
properties: {
198
href: node.url,
199
target: '_blank',
200
rel: 'noopener noreferrer'
201
},
202
children: state.all(node)
203
};
204
},
205
206
// Custom code block handler
207
code(state, node) {
208
return {
209
type: 'element',
210
tagName: 'pre',
211
properties: {
212
className: node.lang ? [`language-${node.lang}`] : undefined
213
},
214
children: [{
215
type: 'element',
216
tagName: 'code',
217
properties: {},
218
children: [{ type: 'text', value: node.value }]
219
}]
220
};
221
}
222
}
223
})
224
```
225
226
#### HTML Output Options
227
228
Additional options from hast-util-to-html for controlling HTML output formatting. These are automatically available through the Options interface.
229
230
```typescript { .api }
231
/** HTML output configuration options (subset of hast-util-to-html options) */
232
interface HtmlOutputOptions {
233
/** Allow dangerous HTML in output */
234
allowDangerousHtml?: boolean | null | undefined;
235
/** Close self-closing tags */
236
closeSelfClosing?: boolean | null | undefined;
237
/** Omit optional closing tags */
238
omitOptionalTags?: boolean | null | undefined;
239
/** Character encoding options */
240
characterReferences?: {
241
useShortestReferences?: boolean;
242
omitOptionalSemicolons?: boolean;
243
} | null | undefined;
244
/** Control quote usage in attributes */
245
quoteSmart?: boolean | null | undefined;
246
/** Collapse empty attributes */
247
collapseEmptyAttributes?: boolean | null | undefined;
248
/** Prefer unquoted attribute values */
249
preferUnquoted?: boolean | null | undefined;
250
}
251
```
252
253
**Examples:**
254
255
```javascript
256
// Control HTML output formatting
257
.use(remarkHtml, {
258
closeSelfClosing: true, // <br /> instead of <br>
259
omitOptionalTags: false, // Always include closing tags
260
characterReferences: {
261
useShortestReferences: true, // Use shortest HTML entities
262
omitOptionalSemicolons: false // Always include semicolons
263
}
264
})
265
```
266
267
## Types
268
269
```typescript { .api }
270
/** Unified plugin type */
271
type Plugin<PluginParameters, Input, Output> = (
272
...parameters: PluginParameters
273
) => void;
274
275
/** Markdown AST root node */
276
interface Root {
277
type: 'root';
278
children: any[];
279
}
280
281
/** Node handlers for mdast to hast conversion */
282
interface Handlers {
283
[nodeType: string]: (state: any, node: any) => any;
284
}
285
286
/** Sanitization schema from hast-util-sanitize */
287
interface Schema {
288
tagNames?: string[];
289
attributes?: Record<string, string[]>;
290
protocols?: Record<string, string[]>;
291
ancestors?: Record<string, string[]>;
292
clobber?: string[];
293
clobberPrefix?: string;
294
strip?: string[];
295
required?: Record<string, Record<string, any>>;
296
allowComments?: boolean;
297
allowDoctypes?: boolean;
298
}
299
```
300
301
## Security Considerations
302
303
- **Default Safety**: remark-html is safe by default with `sanitize: true`
304
- **XSS Prevention**: Built-in sanitization prevents cross-site scripting attacks
305
- **Dangerous Mode**: Setting `sanitize: false` is dangerous and should only be used with trusted input
306
- **Custom Schemas**: When using custom sanitization schemas, ensure they don't allow dangerous tags or attributes
307
308
```javascript
309
// SAFE (recommended)
310
.use(remarkHtml) // sanitize: true by default
311
312
// DANGEROUS - only use with trusted input
313
.use(remarkHtml, { sanitize: false })
314
315
// SAFE with custom restrictions
316
.use(remarkHtml, {
317
sanitize: { tagNames: ['p', 'strong', 'em'] }
318
})
319
```
320
321
## Compatibility
322
323
- **Node.js**: Version 16+
324
- **unified**: Version 6+
325
- **remark**: Version 15+
326
- **Module System**: ESM only
327
- **TypeScript**: Full type definitions included
328
- **Browsers**: Compatible via ESM CDNs like esm.sh
329
330
## Advanced Features
331
332
### Data Fields for HTML Customization
333
334
mdast nodes can include `data` fields to customize HTML output:
335
336
```typescript { .api }
337
interface NodeData {
338
/** Override the HTML tag name */
339
hName?: string;
340
/** Set HTML attributes/properties */
341
hProperties?: Record<string, any>;
342
/** Replace node children with custom HTML */
343
hChildren?: any[];
344
}
345
```
346
347
**Examples:**
348
349
```javascript
350
// Override tag name
351
node.data = { hName: 'section' }; // <p> becomes <section>
352
353
// Add attributes
354
node.data = {
355
hProperties: {
356
className: ['highlight'],
357
id: 'special'
358
}
359
};
360
361
// Replace content
362
node.data = {
363
hChildren: [
364
{ type: 'text', value: 'Custom content' }
365
]
366
};
367
```
368
369
## Error Handling
370
371
- **Unknown Nodes**: Unknown mdast nodes are converted to `<div>` elements
372
- **File Extensions**: Automatically sets output file extension to `.html`
373
- **Newline Handling**: Adds trailing newline to non-empty output for consistency