UNPKG

39.9 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[![tests][tests]][tests-url]
5[![Backers on Open Collective](https://opencollective.com/html-webpack-plugin/backers/badge.svg)](#backers)
6[![Sponsors on Open Collective](https://opencollective.com/html-webpack-plugin/sponsors/badge.svg)](#sponsors)
7
8<div align="center">
9 <img width="200" height="200" src="https://www.w3.org/html/logo/downloads/HTML5_Badge.svg">
10 <a href="https://github.com/webpack/webpack">
11 <img width="200" height="200"
12 src="https://webpack.js.org/assets/icon-square-big.svg">
13 </a>
14 <div>
15 <img width="100" height="100" title="Webpack Plugin" src="http://michael-ciniawsky.github.io/postcss-load-plugins/logo.svg">
16 </div>
17 <h1>HTML Webpack Plugin</h1>
18 <p>Plugin that simplifies creation of HTML files to serve your bundles</p>
19</div>
20
21<h2 align="center">Install</h2>
22
23<h3>Webpack 5</h3>
24
25```bash
26 npm i --save-dev html-webpack-plugin
27```
28
29```bash
30 yarn add --dev html-webpack-plugin
31```
32
33<h3>Webpack 4</h3>
34
35```bash
36 npm i --save-dev html-webpack-plugin@4
37```
38
39```bash
40 yarn add --dev html-webpack-plugin@4
41```
42
43This 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
44your own template using `lodash` templates or use your own loader.
45
46<h2 align="center">Sponsors</h2>
47
48<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>
49<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>
50<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>
51<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>
52<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>
53<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>
54<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>
55<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>
56<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>
57<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>
58
59Thanks for supporting the ongoing improvements to the html-webpack-plugin!
60
61<h2 align="center">Zero Config</h2>
62
63The `html-webpack-plugin` works without configuration.
64It'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).
65
66<h2 align="center">Plugins</h2>
67
68The `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
69
70- [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity) for enhanced asset security
71- [appcache-webpack-plugin](https://github.com/lettertwo/appcache-webpack-plugin) for iOS and Android offline usage
72- [favicons-webpack-plugin](https://github.com/jantimon/favicons-webpack-plugin) which generates favicons and icons for iOS, Android and desktop browsers
73- [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
74- [html-webpack-inline-svg-plugin](https://github.com/thegc/html-webpack-inline-svg-plugin) to inline SVGs in the resulting HTML file.
75- [html-webpack-exclude-assets-plugin](https://github.com/jamesjieye/html-webpack-exclude-assets-plugin) for excluding assets using regular expressions
76- [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).
77- [html-webpack-injector](https://github.com/thearchitgarg/html-webpack-injector) to inject chunks in `head` or `body` (different locations ) of same html document.
78- [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'>`
79- [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
80- [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.
81- [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.
82- [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.
83- [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".
84- [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
85- [strict-csp-html-webpack-plugin](https://github.com/google/strict-csp/tree/main/strict-csp-html-webpack-plugin) to add a [**strict** Content-Security-Policy (CSP)](https://web.dev) as a `meta` tag to the HTML output. A strict CSP is specifically efficient against XSS attacks.
86- [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.
87- [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
88- [html-webpack-inject-preload](https://github.com/principalstudio/html-webpack-inject-preload) allows to add preload links &lt;link rel='preload'> anywhere you want.
89- [inject-body-webpack-plugin](https://github.com/Jaid/inject-body-webpack-plugin) is a simple method of injecting a custom HTML string into the body.
90- [html-webpack-plugin-django](https://github.com/TommasoAmici/html-webpack-plugin-django) a Webpack plugin to inject Django static tags.
91- [html-webpack-inject-attributes-plugin](https://github.com/dyw934854565/html-webpack-inject-attributes-plugin) add extra attributes to inject assetTags.
92- [js-entry-webpack-plugin](https://github.com/liam61/html-webpack-plugin) creates webpack bundles into your js entry
93
94<h2 align="center">Usage</h2>
95
96The plugin will generate an HTML5 file for you that includes all your `webpack`
97bundles in the head using `script` tags. Just add the plugin to your `webpack`
98config as follows:
99
100**webpack.config.js**
101
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: [new HtmlWebpackPlugin()],
112};
113```
114
115This will generate a file `dist/index.html` containing the following
116
117```html
118<!doctype html>
119<html>
120 <head>
121 <meta charset="utf-8" />
122 <title>Webpack App</title>
123 <script defer src="index_bundle.js"></script>
124 </head>
125 <body></body>
126</html>
127```
128
129If you have multiple `webpack` entry points, they will all be included with `script` tags in the generated HTML.
130
131If 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))
132then these will be included with `<link>` tags in the HTML head.
133
134If you have plugins that make use of it, `html-webpack-plugin` should be ordered first before any of the integrated Plugins.
135
136<h2 align="center">Options</h2>
137
138You can pass a hash of configuration options to `html-webpack-plugin`.
139Allowed values are as follows:
140
141| Name | Type | Default | Description |
142| :----------------------: | :--------------------------------------------------: | :---------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
143| **`title`** | `{String}` | `Webpack App` | The title to use for the generated HTML document |
144| **`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'`. |
145| **`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 |
146| **`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 |
147| **`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) |
148| **`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) |
149| **`publicPath`** | `{String\|'auto'}` | `'auto'` | The publicPath used for script and link tags |
150| **`scriptLoading`** | `{'blocking'\|'defer'\|'module'\|'systemjs-module'}` | `'defer'` | Modern browsers support non blocking javascript loading (`'defer'`) to improve the page startup performance. Setting to `'module'` adds attribute [`type="module"`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html). This also implies "defer", since modules are automatically deferred. |
151| **`favicon`** | `{String}` | `` | Adds the given favicon path to the output HTML |
152| **`meta`** | `{Object}` | `{}` | Allows to inject `meta`-tags. E.g. `meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}` |
153| **`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` |
154| **`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. |
155| **`hash`** | `{Boolean}` | `false` | If `true` then append a unique `webpack` compilation hash to all included scripts and CSS files (i.e. `main.js?hash=compilation_hash`). This is useful for cache busting |
156| **`cache`** | `{Boolean}` | `true` | Emit the file only if it was changed |
157| **`showErrors`** | `{Boolean}` | `true` | Errors details will be written into the HTML page |
158| **`chunks`** | `{?}` | `?` | Allows you to add only some chunks (e.g only the unit-test chunk) |
159| **`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}` |
160| **`excludeChunks`** | `{Array.<string>}` | `` | Allows you to skip some chunks (e.g don't add the unit-test chunk) |
161| **`xhtml`** | `{Boolean}` | `false` | If `true` render the `link` tags as self-closing (XHTML compliant) |
162
163Here's an example webpack config illustrating how to use these options
164
165**webpack.config.js**
166
167```js
168{
169 entry: 'index.js',
170 output: {
171 path: __dirname + '/dist',
172 filename: 'index_bundle.js'
173 },
174 plugins: [
175 new HtmlWebpackPlugin({
176 title: 'My App',
177 filename: 'assets/admin.html'
178 })
179 ]
180}
181```
182
183### Generating Multiple HTML Files
184
185To generate more than one HTML file, declare the plugin more than
186once in your plugins array
187
188**webpack.config.js**
189
190```js
191{
192 entry: 'index.js',
193 output: {
194 path: __dirname + '/dist',
195 filename: 'index_bundle.js'
196 },
197 plugins: [
198 new HtmlWebpackPlugin(), // Generates default index.html
199 new HtmlWebpackPlugin({ // Also generate a test.html
200 filename: 'test.html',
201 template: 'src/assets/test.html'
202 })
203 ]
204}
205```
206
207### Writing Your Own Templates
208
209If the default generated HTML doesn't meet your needs you can supply
210your own template. The easiest way is to use the `template` option and pass a custom HTML file.
211The html-webpack-plugin will automatically inject all necessary CSS, JS, manifest
212and favicon files into the markup.
213
214Details of other template loaders are [documented here](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md).
215
216```js
217plugins: [
218 new HtmlWebpackPlugin({
219 title: "Custom template",
220 // Load a custom template (lodash by default)
221 template: "index.html",
222 }),
223];
224```
225
226**index.html**
227
228```html
229<!doctype html>
230<html>
231 <head>
232 <meta charset="utf-8" />
233 <title><%= htmlWebpackPlugin.options.title %></title>
234 </head>
235 <body></body>
236</html>
237```
238
239If you already have a template loader, you can use it to parse the template.
240Please note that this will also happen if you specify the html-loader and use `.html` file as template.
241
242**webpack.config.js**
243
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 - `htmlWebpackPlugin.files`: direct access to the files used during the compilation.
281
282 ```typescript
283 publicPath: string;
284 js: string[];
285 css: string[];
286 manifest?: string;
287 favicon?: string;
288 ```
289
290- `webpackConfig`: the webpack configuration that was used for this compilation. This
291 can be used, for example, to get the `publicPath` (`webpackConfig.output.publicPath`).
292
293- `compilation`: the webpack [compilation object](https://webpack.js.org/api/compilation-object/).
294 This can be used, for example, to get the contents of processed assets and inline them
295 directly in the page, through `compilation.assets[...].source()`
296 (see [the inline template example](examples/inline/template.pug)).
297
298The template can also be directly inlined directly into the options object.
299⚠️ **`templateContent` does not allow to use webpack loaders for your template and will not watch for template file changes**
300
301**webpack.config.js**
302
303```js
304new HtmlWebpackPlugin({
305 templateContent: `
306 <html>
307 <body>
308 <h1>Hello World</h1>
309 </body>
310 </html>
311 `,
312});
313```
314
315The `templateContent` can also access all `templateParameters` values.
316⚠️ **`templateContent` does not allow to use webpack loaders for your template and will not watch for template file changes**
317
318**webpack.config.js**
319
320```js
321new HtmlWebpackPlugin({
322 inject: false,
323 templateContent: ({ htmlWebpackPlugin }) => `
324 <html>
325 <head>
326 ${htmlWebpackPlugin.tags.headTags}
327 </head>
328 <body>
329 <h1>Hello World</h1>
330 ${htmlWebpackPlugin.tags.bodyTags}
331 </body>
332 </html>
333 `,
334});
335```
336
337### Filtering Chunks
338
339To include only certain chunks you can limit the chunks being used
340
341**webpack.config.js**
342
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
355```js
356plugins: [
357 new HtmlWebpackPlugin({
358 excludeChunks: ["dev-helper"],
359 }),
360];
361```
362
363### Minification
364
365If the `minify` option is set to `true` (the default when webpack's `mode` is `'production'`),
366the generated HTML will be minified using [html-minifier-terser](https://github.com/DanielRuf/html-minifier-terser)
367and the following options:
368
369```js
370{
371 collapseWhitespace: true,
372 keepClosingSlash: true,
373 removeComments: true,
374 removeRedundantAttributes: true,
375 removeScriptTypeAttributes: true,
376 removeStyleLinkTypeAttributes: true,
377 useShortDoctype: true
378}
379```
380
381To use custom [html-minifier options](https://github.com/DanielRuf/html-minifier-terser#options-quick-reference)
382pass an object to `minify` instead. This object will not be merged with the defaults above.
383
384To disable minification during production mode set the `minify` option to `false`.
385
386### Meta Tags
387
388If the `meta` option is set the html-webpack-plugin will inject meta tags.
389For the default template the html-webpack-plugin will already provide a default for the `viewport` meta tag.
390
391Please take a look at this well maintained list of almost all [possible meta tags](https://github.com/joshbuchea/HEAD#meta).
392
393#### name/content meta tags
394
395Most meta tags are configured by setting a `name` and a `content` attribute.
396To add those use a key/value pair:
397
398**webpack.config.js**
399
400```js
401plugins: [
402 new HtmlWebpackPlugin({
403 meta: {
404 viewport: "width=device-width, initial-scale=1, shrink-to-fit=no",
405 // Will generate: <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
406 "theme-color": "#4285f4",
407 // Will generate: <meta name="theme-color" content="#4285f4">
408 },
409 }),
410];
411```
412
413#### Simulate http response headers
414
415The **http-equiv** attribute is essentially used to simulate a HTTP response header.
416This format is supported using an object notation which allows you to add any attribute:
417
418**webpack.config.js**
419
420```js
421plugins: [
422 new HtmlWebpackPlugin({
423 meta: {
424 "Content-Security-Policy": {
425 "http-equiv": "Content-Security-Policy",
426 content: "default-src https:",
427 },
428 // Will generate: <meta http-equiv="Content-Security-Policy" content="default-src https:">
429 // Which equals to the following http header: `Content-Security-Policy: default-src https:`
430 "set-cookie": {
431 "http-equiv": "set-cookie",
432 content: "name=value; expires=date; path=url",
433 },
434 // Will generate: <meta http-equiv="set-cookie" content="value; expires=date; path=url">
435 // Which equals to the following http header: `set-cookie: value; expires=date; path=url`
436 },
437 }),
438];
439```
440
441### Base Tag
442
443When the `base` option is used,
444html-webpack-plugin will inject a [base tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base).
445By default, a base tag will not be injected.
446
447The following two are identical and will both insert `<base href="http://example.com/some/page.html">`:
448
449```js
450new HtmlWebpackPlugin({
451 base: "http://example.com/some/page.html",
452});
453```
454
455```js
456new HtmlWebpackPlugin({
457 base: { href: "http://example.com/some/page.html" },
458});
459```
460
461The `target` can be specified with the corresponding key:
462
463```js
464new HtmlWebpackPlugin({
465 base: {
466 href: "http://example.com/some/page.html",
467 target: "_blank",
468 },
469});
470```
471
472which will inject the element `<base href="http://example.com/some/page.html" target="_blank">`.
473
474### Long Term Caching
475
476For long term caching add `contenthash` to the filename.
477
478**Example:**
479
480```js
481plugins: [
482 new HtmlWebpackPlugin({
483 filename: "index.[contenthash].html",
484 }),
485];
486```
487
488`contenthash` is the hash of the content of the output file.
489
490Refer webpack's [Template Strings](https://webpack.js.org/configuration/output/#template-strings) for more details
491
492### Events
493
494To allow other [plugins](https://github.com/webpack/docs/wiki/plugins) to alter the HTML this plugin executes
495[tapable](https://github.com/webpack/tapable/tree/master) hooks.
496
497The [lib/hooks.js](https://github.com/jantimon/html-webpack-plugin/blob/master/lib/hooks.js) contains all information
498about which values are passed.
499
500[![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)
501
502#### `beforeAssetTagGeneration` hook
503
504```
505 AsyncSeriesWaterfallHook<{
506 assets: {
507 publicPath: string,
508 js: Array<{string}>,
509 css: Array<{string}>,
510 favicon?: string | undefined,
511 manifest?: string | undefined
512 },
513 outputName: string,
514 plugin: HtmlWebpackPlugin
515 }>
516```
517
518#### `alterAssetTags` hook
519
520```
521 AsyncSeriesWaterfallHook<{
522 assetTags: {
523 scripts: Array<HtmlTagObject>,
524 styles: Array<HtmlTagObject>,
525 meta: Array<HtmlTagObject>,
526 },
527 publicPath: string,
528 outputName: string,
529 plugin: HtmlWebpackPlugin
530 }>
531```
532
533#### `alterAssetTagGroups` hook
534
535```
536 AsyncSeriesWaterfallHook<{
537 headTags: Array<HtmlTagObject | HtmlTagObject>,
538 bodyTags: Array<HtmlTagObject | HtmlTagObject>,
539 publicPath: string,
540 outputName: string,
541 plugin: HtmlWebpackPlugin
542 }>
543```
544
545#### `afterTemplateExecution` hook
546
547```
548 AsyncSeriesWaterfallHook<{
549 html: string,
550 headTags: Array<HtmlTagObject | HtmlTagObject>,
551 bodyTags: Array<HtmlTagObject | HtmlTagObject>,
552 outputName: string,
553 plugin: HtmlWebpackPlugin,
554 }>
555```
556
557#### `beforeEmit` hook
558
559```
560 AsyncSeriesWaterfallHook<{
561 html: string,
562 outputName: string,
563 plugin: HtmlWebpackPlugin,
564 }>
565```
566
567#### `afterEmit` hook
568
569```
570 AsyncSeriesWaterfallHook<{
571 outputName: string,
572 plugin: HtmlWebpackPlugin
573 }>
574```
575
576Example implementation: [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity)
577
578**plugin.js**
579
580```js
581// If your plugin is direct dependent to the html webpack plugin:
582const HtmlWebpackPlugin = require("html-webpack-plugin");
583// If your plugin is using html-webpack-plugin as an optional dependency
584// you can use https://github.com/tallesl/node-safe-require instead:
585const HtmlWebpackPlugin = require("safe-require")("html-webpack-plugin");
586
587class MyPlugin {
588 apply(compiler) {
589 compiler.hooks.compilation.tap("MyPlugin", (compilation) => {
590 console.log("The compiler is starting a new compilation...");
591
592 // Static Plugin interface |compilation |HOOK NAME | register listener
593 HtmlWebpackPlugin.getCompilationHooks(compilation).beforeEmit.tapAsync(
594 "MyPlugin", // <-- Set a meaningful name here for stacktraces
595 (data, cb) => {
596 // Manipulate the content
597 data.html += "The Magic Footer";
598 // Tell webpack to move on
599 cb(null, data);
600 },
601 );
602 });
603 }
604}
605
606module.exports = MyPlugin;
607```
608
609**webpack.config.js**
610
611```js
612plugins: [new MyPlugin({ options: "" })];
613```
614
615Note that the callback must be passed the HtmlWebpackPluginData in order to pass this onto any other plugins listening on the same `beforeEmit` event
616
617<h2 align="center">Maintainers</h2>
618
619<table>
620 <tbody>
621 <tr>
622 <td align="center">
623 <img width="150" height="150"
624 src="https://avatars3.githubusercontent.com/u/4113649?v=3&s=150">
625 </br>
626 <a href="https://github.com/jantimon">Jan Nicklas</a>
627 </td>
628 <td align="center">
629 <img width="150" height="150"
630 src="https://avatars2.githubusercontent.com/u/4112409?v=3&s=150">
631 </br>
632 <a href="https://github.com/mastilver">Thomas Sileghem</a>
633 </td>
634 </tr>
635 <tbody>
636</table>
637
638## Backers
639
640Thank you to all our backers!
641If 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).
642
643<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>
644<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>
645<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>
646<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>
647<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>
648<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>
649<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>
650<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>
651<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>
652<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>
653
654## Contributors
655
656This project exists thanks to all the people who contribute.
657
658You'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.
659
660<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>
661
662[npm]: https://img.shields.io/npm/v/html-webpack-plugin.svg
663[npm-url]: https://npmjs.com/package/html-webpack-plugin
664[node]: https://img.shields.io/node/v/html-webpack-plugin.svg
665[node-url]: https://nodejs.org
666[tests]: https://github.com/jantimon/html-webpack-plugin/workflows/CI/badge.svg
667[tests-url]: https://github.com/jantimon/html-webpack-plugin/actions?query=workflow%3ACI