UNPKG

29.3 kBMarkdownView Raw
1[![npm][npm]][npm-url]
2[![node][node]][node-url]
3![npm](https://img.shields.io/npm/dw/html-webpack-plugin.svg)
4[![deps][deps]][deps-url]
5[![tests][tests]][tests-url]
6[![Backers on Open Collective](https://opencollective.com/html-webpack-plugin/backers/badge.svg)](#backers)
7 [![Sponsors on Open Collective](https://opencollective.com/html-webpack-plugin/sponsors/badge.svg)](#sponsors)
8
9<div align="center">
10 <img width="200" height="200" src="https://worldvectorlogo.com/logos/html5.svg">
11 <a href="https://github.com/webpack/webpack">
12 <img width="200" height="200"
13 src="https://webpack.js.org/assets/icon-square-big.svg">
14 </a>
15 <div>
16 <img width="100" height="100" title="Webpack Plugin" src="http://michael-ciniawsky.github.io/postcss-load-plugins/logo.svg">
17 </div>
18 <h1>HTML Webpack Plugin</h1>
19 <p>Plugin that simplifies creation of HTML files to serve your bundles</p>
20</div>
21
22<h2 align="center">Install</h2>
23
24<h3>Webpack 5</h3>
25
26```bash
27 npm i --save-dev html-webpack-plugin
28```
29
30```bash
31 yarn add --dev html-webpack-plugin
32```
33
34
35<h3>Webpack 4</h3>
36
37```bash
38 npm i --save-dev html-webpack-plugin@4
39```
40
41```bash
42 yarn add --dev html-webpack-plugin@4
43```
44
45
46This is a [webpack](http://webpack.js.org/) plugin that simplifies creation of HTML files to serve your `webpack` bundles. This is especially useful for `webpack` bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply
47your own template using `lodash` templates or use your own loader.
48
49<h2 align="center">Sponsors</h2>
50
51<a href="https://opencollective.com/html-webpack-plugin/sponsor/0/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/0/avatar.svg"></a>
52<a href="https://opencollective.com/html-webpack-plugin/sponsor/1/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/1/avatar.svg"></a>
53<a href="https://opencollective.com/html-webpack-plugin/sponsor/2/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/2/avatar.svg"></a>
54<a href="https://opencollective.com/html-webpack-plugin/sponsor/3/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/3/avatar.svg"></a>
55<a href="https://opencollective.com/html-webpack-plugin/sponsor/4/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/4/avatar.svg"></a>
56<a href="https://opencollective.com/html-webpack-plugin/sponsor/5/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/5/avatar.svg"></a>
57<a href="https://opencollective.com/html-webpack-plugin/sponsor/6/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/6/avatar.svg"></a>
58<a href="https://opencollective.com/html-webpack-plugin/sponsor/7/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/7/avatar.svg"></a>
59<a href="https://opencollective.com/html-webpack-plugin/sponsor/8/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/8/avatar.svg"></a>
60<a href="https://opencollective.com/html-webpack-plugin/sponsor/9/website" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/sponsor/9/avatar.svg"></a>
61
62Thanks for supporting the ongoing improvements to the html-webpack-plugin!
63
64<h2 align="center">Zero Config</h2>
65
66The `html-webpack-plugin` works without configuration.
67It's a great addition to the [⚙️ webpack-config-plugins](https://github.com/namics/webpack-config-plugins/blob/master/README.md#zero-config-webpack-dev-server-example).
68
69<h2 align="center">Plugins</h2>
70
71The `html-webpack-plugin` provides [hooks](https://github.com/jantimon/html-webpack-plugin#events) to extend it to your needs. There are already some really powerful plugins which can be integrated with zero configuration
72
73 * [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity) for enhanced asset security
74 * [appcache-webpack-plugin](https://github.com/lettertwo/appcache-webpack-plugin) for iOS and Android offline usage
75 * [favicons-webpack-plugin](https://github.com/jantimon/favicons-webpack-plugin) which generates favicons and icons for iOS, Android and desktop browsers
76 * [html-webpack-harddisk-plugin](https://github.com/jantimon/html-webpack-harddisk-plugin) can be used to always write to disk the html file, useful when webpack-dev-server / HMR are being used
77 * [html-webpack-inline-svg-plugin](https://github.com/thegc/html-webpack-inline-svg-plugin) to inline SVGs in the resulting HTML file.
78 * [html-webpack-exclude-assets-plugin](https://github.com/jamesjieye/html-webpack-exclude-assets-plugin) for excluding assets using regular expressions
79 * [html-webpack-include-assets-plugin](https://github.com/jharris4/html-webpack-include-assets-plugin) for including lists of js or css file paths (such as those copied by the copy-webpack-plugin).
80 * [html-webpack-injector](https://github.com/thearchitgarg/html-webpack-injector) to inject chunks in `head` or `body` (different locations ) of same html document.
81 * [resource-hints-webpack-plugin](https://github.com/jantimon/resource-hints-webpack-plugin) to add resource hints for faster initial page loads using `<link rel='preload'>` and `<link rel='prefetch'>`
82 * [preload-webpack-plugin](https://github.com/GoogleChrome/preload-webpack-plugin) for automatically wiring up asynchronous (and other types) of JavaScript chunks using `<link rel='preload'>` helping with lazy-loading
83 * [link-media-html-webpack-plugin](https://github.com/yaycmyk/link-media-html-webpack-plugin) allows for injected stylesheet `<link />` tags to have their media attribute set automatically; useful for providing specific desktop/mobile/print etc. stylesheets that the browser will conditionally download
84 * [html-webpack-inline-style-plugin](https://github.com/djaax/html-webpack-inline-style-plugin) for inlining styles to HTML elements using [juice](https://github.com/Automattic/juice). Useful for email generation automatisation.
85 * [html-webpack-exclude-empty-assets-plugin](https://github.com/KnisterPeter/html-webpack-exclude-empty-assets-plugin) removes empty assets from being added to the html. This fixes some problems with extract-text-plugin with webpack 4.
86 * [webpack-concat-plugin](https://github.com/hxlniada/webpack-concat-plugin) for concat and uglify files that needn't to be webpack bundles(for legacy files) and inject to html-webpack-plugin.
87 * [html-webpack-link-type-plugin](https://github.com/steadyapp/html-webpack-link-type-plugin) adds a configurable mimetype to resources injected as links (such as adding type="text/css" to external stylesheets) for compatibility with "strict mode".
88 * [csp-html-webpack-plugin](https://github.com/slackhq/csp-html-webpack-plugin) to add [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) meta tags to the HTML output
89 * [webpack-nomodule-plugin](https://github.com/swimmadude66/webpack-nomodule-plugin) allows you to add a `nomodule` attribute to specific injected scripts, which prevents the scripts from being loaded by newer browsers. Good for limiting loads of polyfills.
90 * [html-webpack-skip-assets-plugin](https://github.com/swimmadude66/html-webpack-skip-assets-plugin) Skip adding certain output files to the html file. Built as a drop-in replacement for [html-webpack-exclude-assets-plugin](https://www.npmjs.com/package/html-webpack-exclude-assets-plugin) and works with newer [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) versions
91 * [html-webpack-inject-preload](https://github.com/principalstudio/html-webpack-inject-preload) allows to add preload links &lt;link rel='preload'> anywhere you want.
92
93
94
95<h2 align="center">Usage</h2>
96
97The plugin will generate an HTML5 file for you that includes all your `webpack`
98bundles in the body using `script` tags. Just add the plugin to your `webpack`
99config as follows:
100
101**webpack.config.js**
102```js
103const HtmlWebpackPlugin = require('html-webpack-plugin')
104
105module.exports = {
106 entry: 'index.js',
107 output: {
108 path: __dirname + '/dist',
109 filename: 'index_bundle.js'
110 },
111 plugins: [
112 new HtmlWebpackPlugin()
113 ]
114}
115```
116
117This will generate a file `dist/index.html` containing the following
118
119```html
120<!DOCTYPE html>
121<html>
122 <head>
123 <meta charset="utf-8">
124 <title>Webpack App</title>
125 </head>
126 <body>
127 <script src="index_bundle.js"></script>
128 </body>
129</html>
130```
131
132If you have multiple `webpack` entry points, they will all be included with `script` tags in the generated HTML.
133
134If you have any CSS assets in webpack's output (for example, CSS extracted with the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin))
135then these will be included with `<link>` tags in the HTML head.
136
137If you have plugins that make use of it, `html-webpack-plugin` should be ordered first before any of the integrated Plugins.
138
139<h2 align="center">Options</h2>
140
141You can pass a hash of configuration options to `html-webpack-plugin`.
142Allowed values are as follows:
143
144|Name|Type|Default|Description|
145|:--:|:--:|:-----:|:----------|
146|**`title`**|`{String}`|`Webpack App`|The title to use for the generated HTML document|
147|**`filename`**|`{String\|Function}`|`'index.html'`|The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`). The `[name]` placeholder will be replaced with the entry name. Can also be a function e.g. `(entryName) => entryName + '.html'`. |
148|**`template`**|`{String}`|``|`webpack` relative or absolute path to the template. By default it will use `src/index.ejs` if it exists. Please see the [docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md) for details|
149|**`templateContent`**|`{string\|Function\|false}`|false| Can be used instead of `template` to provide an inline template - please read the [Writing Your Own Templates](https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates) section |
150|**`templateParameters`**|`{Boolean\|Object\|Function}`| `false`| Allows to overwrite the parameters used in the template - see [example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/template-parameters) |
151|**`inject`**|`{Boolean\|String}`|`true`|`true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element. Passing `true` will add it to the head/body depending on the `scriptLoading` option. Passing `false` will disable automatic injections. - see the [inject:false example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/custom-insertion-position)|
152|**`publicPath`**|`{String\|'auto'}`|`'auto'`|The publicPath used for script and link tags|
153|**`scriptLoading`**|`{'blocking'\|'defer'}`|`'defer'`| Modern browsers support non blocking javascript loading (`'defer'`) to improve the page startup performance. |
154|**`favicon`**|`{String}`|``|Adds the given favicon path to the output HTML|
155|**`meta`**|`{Object}`|`{}`|Allows to inject `meta`-tags. E.g. `meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}`|
156|**`base`**|`{Object\|String\|false}`|`false`|Inject a [`base`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) tag. E.g. `base: "https://example.com/path/page.html`|
157|**`minify`**|`{Boolean\|Object}`|`true` if `mode` is `'production'`, otherwise `false`|Controls if and in what ways the output should be minified. See [minification](#minification) below for more details.|
158|**`hash`**|`{Boolean}`|`false`|If `true` then append a unique `webpack` compilation hash to all included scripts and CSS files. This is useful for cache busting|
159|**`cache`**|`{Boolean}`|`true`|Emit the file only if it was changed|
160|**`showErrors`**|`{Boolean}`|`true`|Errors details will be written into the HTML page|
161|**`chunks`**|`{?}`|`?`|Allows you to add only some chunks (e.g only the unit-test chunk)|
162|**`chunksSortMode`**|`{String\|Function}`|`auto`|Allows to control how chunks should be sorted before they are included to the HTML. Allowed values are `'none' \| 'auto' \| 'manual' \| {Function}`|
163|**`excludeChunks`**|`{Array.<string>}`|``|Allows you to skip some chunks (e.g don't add the unit-test chunk)|
164|**`xhtml`**|`{Boolean}`|`false`|If `true` render the `link` tags as self-closing (XHTML compliant)|
165
166Here's an example webpack config illustrating how to use these options
167
168**webpack.config.js**
169```js
170{
171 entry: 'index.js',
172 output: {
173 path: __dirname + '/dist',
174 filename: 'index_bundle.js'
175 },
176 plugins: [
177 new HtmlWebpackPlugin({
178 title: 'My App',
179 filename: 'assets/admin.html'
180 })
181 ]
182}
183```
184
185### Generating Multiple HTML Files
186
187To generate more than one HTML file, declare the plugin more than
188once in your plugins array
189
190**webpack.config.js**
191```js
192{
193 entry: 'index.js',
194 output: {
195 path: __dirname + '/dist',
196 filename: 'index_bundle.js'
197 },
198 plugins: [
199 new HtmlWebpackPlugin(), // Generates default index.html
200 new HtmlWebpackPlugin({ // Also generate a test.html
201 filename: 'test.html',
202 template: 'src/assets/test.html'
203 })
204 ]
205}
206```
207
208### Writing Your Own Templates
209
210If the default generated HTML doesn't meet your needs you can supply
211your own template. The easiest way is to use the `template` option and pass a custom HTML file.
212The html-webpack-plugin will automatically inject all necessary CSS, JS, manifest
213and favicon files into the markup.
214
215Details of other template loaders are [documented here](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md).
216
217```js
218plugins: [
219 new HtmlWebpackPlugin({
220 title: 'Custom template',
221 // Load a custom template (lodash by default)
222 template: 'index.html'
223 })
224]
225```
226
227**index.html**
228```html
229<!DOCTYPE html>
230<html>
231 <head>
232 <meta charset="utf-8"/>
233 <title><%= htmlWebpackPlugin.options.title %></title>
234 </head>
235 <body>
236 </body>
237</html>
238```
239
240If you already have a template loader, you can use it to parse the template.
241Please note that this will also happen if you specify the html-loader and use `.html` file as template.
242
243**webpack.config.js**
244```js
245module: {
246 loaders: [
247 { test: /\.hbs$/, loader: "handlebars-loader" }
248 ]
249},
250plugins: [
251 new HtmlWebpackPlugin({
252 title: 'Custom template using Handlebars',
253 template: 'index.hbs'
254 })
255]
256```
257
258You can use the `lodash` syntax out of the box. If the `inject` feature doesn't fit your needs and you want full control over the asset placement use the [default template](https://github.com/jaketrent/html-webpack-template/blob/86f285d5c790a6c15263f5cc50fd666d51f974fd/index.html) of the [html-webpack-template project](https://github.com/jaketrent/html-webpack-template) as a starting point for writing your own.
259
260The following variables are available in the template by default (you can extend them using the `templateParameters` option):
261
262- `htmlWebpackPlugin`: data specific to this plugin
263
264 - `htmlWebpackPlugin.options`: the options hash that was passed to
265 the plugin. In addition to the options actually used by this plugin,
266 you can use this hash to pass arbitrary data through to your template.
267
268 - `htmlWebpackPlugin.tags`: the prepared `headTags` and `bodyTags` Array to render the `<base>`, `<meta>`, `<script>` and `<link>` tags.
269 Can be used directly in templates and literals. For example:
270 ```html
271 <html>
272 <head>
273 <%= htmlWebpackPlugin.tags.headTags %>
274 </head>
275 <body>
276 <%= htmlWebpackPlugin.tags.bodyTags %>
277 </body>
278 </html>
279 ```
280
281 - `htmlWebpackPlugin.files`: direct access to the files used during the compilation.
282
283 ```typescript
284 publicPath: string;
285 js: string[];
286 css: string[];
287 manifest?: string;
288 favicon?: string;
289 ```
290
291
292- `webpackConfig`: the webpack configuration that was used for this compilation. This
293 can be used, for example, to get the `publicPath` (`webpackConfig.output.publicPath`).
294
295- `compilation`: the webpack [compilation object](https://webpack.js.org/api/compilation-object/).
296 This can be used, for example, to get the contents of processed assets and inline them
297 directly in the page, through `compilation.assets[...].source()`
298 (see [the inline template example](examples/inline/template.pug)).
299
300
301The template can also be directly inlined directly into the options object.
302⚠️ **`templateContent` does not allow to use webpack loaders for your template and will not watch for template file changes**
303
304**webpack.config.js**
305```js
306new HtmlWebpackPlugin({
307 templateContent: `
308 <html>
309 <body>
310 <h1>Hello World</h1>
311 </body>
312 </html>
313 `
314})
315```
316
317The `templateContent` can also access all `templateParameters` values.
318⚠️ **`templateContent` does not allow to use webpack loaders for your template and will not watch for template file changes**
319
320**webpack.config.js**
321```js
322new HtmlWebpackPlugin({
323 inject: false,
324 templateContent: ({htmlWebpackPlugin}) => `
325 <html>
326 <head>
327 ${htmlWebpackPlugin.tags.headTags}
328 </head>
329 <body>
330 <h1>Hello World</h1>
331 ${htmlWebpackPlugin.tags.bodyTags}
332 </body>
333 </html>
334 `
335})
336```
337
338### Filtering Chunks
339
340To include only certain chunks you can limit the chunks being used
341
342**webpack.config.js**
343```js
344plugins: [
345 new HtmlWebpackPlugin({
346 chunks: ['app']
347 })
348]
349```
350
351It is also possible to exclude certain chunks by setting the `excludeChunks` option
352
353**webpack.config.js**
354```js
355plugins: [
356 new HtmlWebpackPlugin({
357 excludeChunks: [ 'dev-helper' ]
358 })
359]
360```
361
362### Minification
363
364If the `minify` option is set to `true` (the default when webpack's `mode` is `'production'`),
365the generated HTML will be minified using [html-minifier-terser](https://github.com/DanielRuf/html-minifier-terser)
366and the following options:
367
368```js
369{
370 collapseWhitespace: true,
371 keepClosingSlash: true,
372 removeComments: true,
373 removeRedundantAttributes: true,
374 removeScriptTypeAttributes: true,
375 removeStyleLinkTypeAttributes: true,
376 useShortDoctype: true
377}
378```
379
380To use custom [html-minifier options](https://github.com/DanielRuf/html-minifier-terser#options-quick-reference)
381pass an object to `minify` instead. This object will not be merged with the defaults above.
382
383To disable minification during production mode set the `minify` option to `false`.
384
385### Meta Tags
386
387If the `meta` option is set the html-webpack-plugin will inject meta tags.
388For the default template the html-webpack-plugin will already provide a default for the `viewport` meta tag.
389
390Please take a look at this well maintained list of almost all [possible meta tags](https://github.com/joshbuchea/HEAD#meta).
391
392#### name/content meta tags
393
394Most meta tags are configured by setting a `name` and a `content` attribute.
395To add those use a key/value pair:
396
397**webpack.config.js**
398```js
399plugins: [
400 new HtmlWebpackPlugin({
401 'meta': {
402 'viewport': 'width=device-width, initial-scale=1, shrink-to-fit=no',
403 // Will generate: <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
404 'theme-color': '#4285f4'
405 // Will generate: <meta name="theme-color" content="#4285f4">
406 }
407 })
408]
409```
410
411#### Simulate http response headers
412
413The **http-equiv** attribute is essentially used to simulate a HTTP response header.
414This format is supported using an object notation which allows you to add any attribute:
415
416**webpack.config.js**
417```js
418plugins: [
419 new HtmlWebpackPlugin({
420 'meta': {
421 'Content-Security-Policy': { 'http-equiv': 'Content-Security-Policy', 'content': 'default-src https:' },
422 // Will generate: <meta http-equiv="Content-Security-Policy" content="default-src https:">
423 // Which equals to the following http header: `Content-Security-Policy: default-src https:`
424 'set-cookie': { 'http-equiv': 'set-cookie', content: 'name=value; expires=date; path=url' },
425 // Will generate: <meta http-equiv="set-cookie" content="value; expires=date; path=url">
426 // Which equals to the following http header: `set-cookie: value; expires=date; path=url`
427 }
428 })
429]
430```
431
432### Base Tag
433
434When the `base` option is used,
435html-webpack-plugin will inject a [base tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base).
436By default, a base tag will not be injected.
437
438The following two are identical and will both insert `<base href="http://example.com/some/page.html">`:
439
440```js
441new HtmlWebpackPlugin({
442 'base': 'http://example.com/some/page.html'
443})
444```
445
446```js
447new HtmlWebpackPlugin({
448 'base': { 'href': 'http://example.com/some/page.html' }
449})
450```
451
452The `target` can be specified with the corresponding key:
453
454```js
455new HtmlWebpackPlugin({
456 'base': {
457 'href': 'http://example.com/some/page.html',
458 'target': '_blank'
459 }
460})
461```
462
463which will inject the element `<base href="http://example.com/some/page.html" target="_blank">`.
464
465### Long Term Caching
466
467For long term caching add `contenthash/templatehash` to the filename.
468
469**Example:**
470
471```js
472plugins: [
473 new HtmlWebpackPlugin({
474 filename: 'index.[contenthash].html'
475 })
476]
477```
478
479`contenthash/templatehash` is the hash of the content of the output file.
480
481Optionally, You can configure like `[<hashType>:contenthash:<digestType>:<length>]`
482
483* `hashType` - one of `sha1`, `md5`, `sha256`, `sha512` or any other node.js supported hash type
484* `digestType` - one of `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
485* `maxlength` - maximum length of the generated hash in chars
486
487**Defaults:** `[md5:contenthash:hex:9999]`
488
489### Events
490
491To allow other [plugins](https://github.com/webpack/docs/wiki/plugins) to alter the HTML this plugin executes
492[tapable](https://github.com/webpack/tapable/tree/master) hooks.
493
494The [lib/hooks.js](https://github.com/jantimon/html-webpack-plugin/blob/master/lib/hooks.js) contains all information
495about which values are passed.
496
497[![Concept flow uml](https://raw.githubusercontent.com/jantimon/html-webpack-plugin/master/flow.png)](https://github.com/jantimon/html-webpack-plugin/blob/master/flow.puml)
498
499#### `beforeAssetTagGeneration` hook
500
501```
502 AsyncSeriesWaterfallHook<{
503 assets: {
504 publicPath: string,
505 js: Array<{string}>,
506 css: Array<{string}>,
507 favicon?: string | undefined,
508 manifest?: string | undefined
509 },
510 outputName: string,
511 plugin: HtmlWebpackPlugin
512 }>
513```
514
515#### `alterAssetTags` hook
516
517```
518 AsyncSeriesWaterfallHook<{
519 assetTags: {
520 scripts: Array<HtmlTagObject>,
521 styles: Array<HtmlTagObject>,
522 meta: Array<HtmlTagObject>,
523 },
524 publicPath: string,
525 outputName: string,
526 plugin: HtmlWebpackPlugin
527 }>
528```
529
530#### `alterAssetTagGroups` hook
531
532```
533 AsyncSeriesWaterfallHook<{
534 headTags: Array<HtmlTagObject | HtmlTagObject>,
535 bodyTags: Array<HtmlTagObject | HtmlTagObject>,
536 publicPath: string,
537 outputName: string,
538 plugin: HtmlWebpackPlugin
539 }>
540```
541
542#### `afterTemplateExecution` hook
543
544```
545 AsyncSeriesWaterfallHook<{
546 html: string,
547 headTags: Array<HtmlTagObject | HtmlTagObject>,
548 bodyTags: Array<HtmlTagObject | HtmlTagObject>,
549 outputName: string,
550 plugin: HtmlWebpackPlugin,
551 }>
552```
553
554#### `beforeEmit` hook
555
556```
557 AsyncSeriesWaterfallHook<{
558 html: string,
559 outputName: string,
560 plugin: HtmlWebpackPlugin,
561 }>
562```
563
564#### `afterEmit` hook
565
566```
567 AsyncSeriesWaterfallHook<{
568 outputName: string,
569 plugin: HtmlWebpackPlugin
570 }>
571```
572
573Example implementation: [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity)
574
575**plugin.js**
576```js
577// If your plugin is direct dependent to the html webpack plugin:
578const HtmlWebpackPlugin = require('html-webpack-plugin');
579// If your plugin is using html-webpack-plugin as an optional dependency
580// you can use https://github.com/tallesl/node-safe-require instead:
581const HtmlWebpackPlugin = require('safe-require')('html-webpack-plugin');
582
583class MyPlugin {
584 apply (compiler) {
585 compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
586 console.log('The compiler is starting a new compilation...')
587
588 // Static Plugin interface |compilation |HOOK NAME | register listener
589 HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
590 'MyPlugin', // <-- Set a meaningful name here for stacktraces
591 (data, cb) => {
592 // Manipulate the content
593 data.html += 'The Magic Footer'
594 // Tell webpack to move on
595 cb(null, data)
596 }
597 )
598 })
599 }
600}
601
602module.exports = MyPlugin
603```
604
605**webpack.config.js**
606```js
607plugins: [
608 new MyPlugin({ options: '' })
609]
610```
611
612Note that the callback must be passed the HtmlWebpackPluginData in order to pass this onto any other plugins listening on the same `beforeEmit` event
613
614<h2 align="center">Maintainers</h2>
615
616<table>
617 <tbody>
618 <tr>
619 <td align="center">
620 <img width="150" height="150"
621 src="https://avatars3.githubusercontent.com/u/4113649?v=3&s=150">
622 </br>
623 <a href="https://github.com/jantimon">Jan Nicklas</a>
624 </td>
625 <td align="center">
626 <img width="150" height="150"
627 src="https://avatars2.githubusercontent.com/u/4112409?v=3&s=150">
628 </br>
629 <a href="https://github.com/mastilver">Thomas Sileghem</a>
630 </td>
631 </tr>
632 <tbody>
633</table>
634
635
636## Backers
637
638Thank you to all our backers!
639If you want to support the project as well [become a sponsor](https://opencollective.com/html-webpack-plugin#sponsor) or a [a backer](https://opencollective.com/html-webpack-plugin#backer).
640
641<a href="https://opencollective.com/html-webpack-plugin/backer/0/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/0/avatar.svg?requireActive=false"></a>
642<a href="https://opencollective.com/html-webpack-plugin/backer/1/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/1/avatar.svg?requireActive=false"></a>
643<a href="https://opencollective.com/html-webpack-plugin/backer/2/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/2/avatar.svg?requireActive=false"></a>
644<a href="https://opencollective.com/html-webpack-plugin/backer/3/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/3/avatar.svg?requireActive=false"></a>
645<a href="https://opencollective.com/html-webpack-plugin/backer/4/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/4/avatar.svg?requireActive=false"></a>
646<a href="https://opencollective.com/html-webpack-plugin/backer/5/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/5/avatar.svg?requireActive=false"></a>
647<a href="https://opencollective.com/html-webpack-plugin/backer/6/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/6/avatar.svg?requireActive=false"></a>
648<a href="https://opencollective.com/html-webpack-plugin/backer/7/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/7/avatar.svg?requireActive=false"></a>
649<a href="https://opencollective.com/html-webpack-plugin/backer/8/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/8/avatar.svg?requireActive=false"></a>
650<a href="https://opencollective.com/html-webpack-plugin/backer/9/website?requireActive=false" target="_blank"><img src="https://opencollective.com/html-webpack-plugin/backer/9/avatar.svg?requireActive=false"></a>
651
652
653## Contributors
654
655This project exists thanks to all the people who contribute.
656
657You're free to contribute to this project by submitting [issues](https://github.com/jantimon/html-webpack-plugin/issues) and/or [pull requests](https://github.com/jantimon/html-webpack-plugin/pulls). This project is test-driven, so keep in mind that every change and new feature should be covered by tests.
658
659This project uses the [semistandard code style](https://github.com/Flet/semistandard).
660
661<a href="https://github.com/jantimon/html-webpack-plugin/graphs/contributors"><img src="https://opencollective.com/html-webpack-plugin/contributors.svg?width=890&button=false" /></a>
662
663
664[npm]: https://img.shields.io/npm/v/html-webpack-plugin.svg
665[npm-url]: https://npmjs.com/package/html-webpack-plugin
666
667[node]: https://img.shields.io/node/v/html-webpack-plugin.svg
668[node-url]: https://nodejs.org
669
670[deps]: https://david-dm.org/jantimon/html-webpack-plugin.svg
671[deps-url]: https://david-dm.org/jantimon/html-webpack-plugin
672
673[tests]: https://github.com/jantimon/html-webpack-plugin/workflows/CI/badge.svg
674[tests-url]: https://github.com/jantimon/html-webpack-plugin/actions?query=workflow%3ACI