Skip to main content

integrity

Option: integrity

Type: 'auto'|boolean|IntegrityOptions Default: false

The subresource integrity hash is a cryptographic value of the integrity attribute that used by a browser to verify that the content of an asset has not been manipulated. If the asset has been manipulated, the browser will never load it.

The Bundler Plugin generates the integrity hashes and adds the integrity attribute to the link and script tags when generating HTML.

No additional plugins required. This plugin computes integrity hashes itself.

type IntegrityOptions = {
enabled?: 'auto' | boolean;
hashFunctions?: HashFunctions | Array<HashFunctions>;
};
type HashFunctions = 'sha256' | 'sha384' | 'sha512';

If the integrity option is an object, then default options are:

{
enabled: 'auto',
hashFunctions: 'sha384',
}
info

The W3C recommends using the SHA-384 hash algorithm.

The integrity or integrity.enabled has one of values:

  • auto - enable the integrity when Webpack mode is production and disable it when mode is development
  • true - enable
  • false - disable

The hashFunctions option can be a string to specify a single hash function name, or an array to specify multiple hash functions for compatibility with many browsers.

warning

When used the integrity option:

  • The js.filename and css.filename options must contain the contenthash.

  • The output.crossOriginLoading Webpack option must be specified as 'use-credentials' or 'anonymous'. The bundler plugin adds the crossorigin attribute with the value defined in the crossOriginLoading. The crossorigin attribute tells the browser to request the script with CORS enabled, which is necessary because the integrity check fails without CORS.

  • The optimization.realContentHash Webpack option must be enabled, by default is enabled in production mode only.

This requirement is necessary to avoid the case where the browser tries to load a contents of a file from the local cache since the filename has not changed, but the integrity value has changed on the server. In this case, the browser will not load the file because the integrity of the cached file computed by the browser will not match the integrity attribute computed on the server.

Add the integrity option in the Webpack config:

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
output: {
// required for `integrity` to work in the browser
crossOriginLoading: 'anonymous',
},
plugins: [
new HtmlBundlerPlugin({
entry: {
index: 'src/views/index.html', // template where are included link and script tags
},
js: {
filename: '[name].[contenthash:8].js', // the filename must contains a contenthash
},
css: {
filename: '[name].[contenthash:8].js', // the filename must contains a contenthash
},
integrity: 'auto', // enable in `production`, disable in `development` mode
}),
],
};

The source HTML template src/views/index.html:

<html>
<head>
<!-- include source style -->
<link href="./style.scss" rel="stylesheet" />
<!-- include source script -->
<script src="./main.js" defer="defer"></script>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>

The generated HTML contains the integrity hashes:

<html>
<head>
<link
href="style.1234abcd.css"
rel="stylesheet"
integrity="sha384-gaDmgJjLpipN1Jmuc98geFnDjVqWn1fixlG0Ab90qFyUIJ4ARXlKBsMGumxTSu7E"
crossorigin="anonymous" />

<script
src="main.abcd1234.js"
defer="defer"
integrity="sha384-E4IoJ3Xutt/6tUVDjvtPwDTTlCfU5oG199UoqWShFCNx6mb4tdpcPLu7sLzNc8Pe"
crossorigin="anonymous"></script>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>

See the integrityHashes hook.