posthtml-hash
is a PostHTML plugin for hashing file names to enable caching.
<html>
<head>
- <link rel="stylesheet" href="styles.[hash].css" />
+ <link rel="stylesheet" href="styles.9a6cf95c41e87b9dc102.css" />
</head>
<body>
- <script src="src.[hash].js"></script>
+ <script src="src.b0dcc67ffc1fd562f212.js"></script>
</body>
</html>
# Yarn
yarn add -D posthtml-hash
# npm
npm i -D posthtml-hash
# pnpm
pnpm i -D posthtml-hash
By default, the plugin will attempt to hash file names that contain [hash]
. As an additional qualifier, only nodes containing href
, src
, or content
attributes are eligible.
<html>
<head>
<!-- ✅ hashed -->
<link rel="stylesheet" href="style.[hash].css" />
<!-- ❌ not hashed -->
<link rel="stylesheet" href="reset.css" />
</head>
<body>
<!-- ✅ hashed -->
<script src="src.[hash].js"></script>
<!-- ❌ not hashed -->
<script src="analytics.js"></script>
</body>
</html>
The recommended usage of this plugin is to incorporate it in your post-build process.
Let's say that you use Rollup to bundle and minify your CSS and JavaScript. The template index.html
is copied to the build
folder.
// postbuild.js
const fs = require("fs");
const posthtml = require("posthtml");
const { hash } = require("posthtml-hash");
const html = fs.readFileSync("./build/index.html");
posthtml()
.use(hash({ path: "build" }))
.process(html)
.then((result) => fs.writeFileSync("./build/index.html", result.html));
For convenience, you can add the post-build script to your package.json. The postbuild
script is automatically invoked following the build
script.
{
"scripts": {
"build": "rollup -c",
"postbuild": "node postbuild.js"
}
}
Customize the hash length by specifying an integer after the hash:{NUMBER}
. The default hash length is 20
.
Note: This only works for a pattern that uses square brackets and a colon separator. Use the hashLength
option for different patterns.
<script src="src.[hash].js"></script>
<!-- src.b0dcc67ffc1fd562f212.js -->
<script src="src.[hash:8].js"></script>
<!-- src.b0dcc67f.js -->
This plugin assumes that the file to process is in the same directory as the PostHTML script. If not, specify the relative path to the html file in options.path
:
hash({
/**
* Relative path to the HTML file being processed
* @default ""
*/
path: "public",
/**
* File name pattern (regular expression) to match
* @default new RegExp(/\[hash.*]/g)
*/
pattern: new RegExp(/custom-file-pattern/),
/**
* Hash length
* @default 20
*/
hashLength: 8,
/**
* Transform the href/src/content attribute value to a relative file path
* @default (filepath) => filepath
*/
transformPath: (filepath) => filepath.replace("https://example.com/", ""),
});
hash({
pattern: new RegExp(/custom-file-pattern/),
hashLength: 8,
});
Result:
- <script src="script.custom-file-pattern.js"></script>
+ <script src="script.b0dcc67f.js"></script>
Input HTML:
<head>
<meta charset="utf-8" />
<!-- We want to hash this image file name and preserve the remote origin URL -->
<meta property="og:image" content="https://example.com/image.[hash].png" />
</head>
hash({
transformPath: (filepath) => {
// removes the targeted remote origin URL when looking up the files locally
return filepath.replace("https://example.com/", "");
},
});
See the examples folder for end-to-end use cases.
See the PostHTML Guidelines.