How To Use Asset Fingerprinting with Eleventy

    In this guide, we'll walk through how to use asset fingerprinting in an Eleventy project.

    1Set up Webpack

    This guide assumes you have Webpack installed in your Eleventy project. If you haven't already, follow this guide to prepare your project:

    How To Use Webpack in an Eleventy Project

    2Install dependencies

    Run the following command to install the Webpack Manifest plugin:

    npm install --save-dev webpack-manifest-plugin

    3Configure the manifest plugin

    Update your webpack.config.js file and make the following changes:

    • Add the ManifestPlugin to your list of plugins
    • Update the filename to include a [contenthash] in production mode

    It should look something like this:

    const path = require('path');
    const ManifestPlugin = require('webpack-manifest-plugin');
    module.exports = (_env, argv) => {
    return {
    entry: './src/scripts/main.js',
    output: {
    path: path.resolve(__dirname, '_site/assets'),
    filename:
    argv.mode === 'production' ? '[name].[contenthash].js' : '[name].js'
    },
    plugins: [new ManifestPlugin()]
    };
    };

    This tells Webpack to create a manifest.json file that contains a mapping of original file names to the outputted filenames containing a unique hash.

    4Add an Eleventy filter

    Open up your .eleventy.js file and add an assetPath filter:

    const fs = require('fs');
    const path = require('path');
    module.exports = function(eleventyConfig) {
    const outputDir = '_site';
    const assetDir = 'assets';
    eleventyConfig.addFilter('assetPath', function(value) {
    if (process.env.ELEVENTY_ENV === 'production') {
    const manifestPath = path.resolve(
    __dirname,
    outputDir,
    assetDir,
    'manifest.json'
    );
    const manifest = JSON.parse(fs.readFileSync(manifestPath));
    return `/${assetDir}/${manifest[value]}`;
    }
    return `/${assetDir}/${value}`;
    });
    return {
    dir: { input: 'src', output: outputDir }
    };
    };

    In production, this filter will read the manifest.json file and return the asset path containing the content hash.

    5Update asset references

    When referencing your assets, use the assetPath filter. For example, your layout file might look like this:

    <!doctype html>
    <html lang="en">
    <head>
    <title>{{ title }}</title>
    </head>
    <body>
    {{ content | safe }}
    <script src="{{ 'main.js' | assetPath }}"></script>
    </body>
    </html>