Asset Fingerprinting
Asset fingerprinting appends a content hash to CSS and JS filenames during accent build, producing immutable URLs that CDNs and browsers can cache indefinitely. When the file content changes, the hash changes, and browsers automatically fetch the new version.
Quick Start
- Enable fingerprinting in
config.yaml:
build: fingerprint: enabled: true
- Use the
| fingerprintfilter in your templates:
{% for css in theme.assets.css %}
<link rel="stylesheet" href="/{{ ('theme/assets/' ~ css) | fingerprint }}">
{% endfor %}
- Build your site:
accent build --output ./public --base-url https://example.com
The output will contain both the original and fingerprinted files:
public/theme/assets/css/
main.css # Original (kept for compatibility)
main.64aee5ca8b.css # Fingerprinted copy
How It Works
During accent build, after theme assets are copied and Sass/SCSS styles are compiled:
- The build walks
output/theme/assets/and matches files against the include/exclude patterns. - For each matched file, it computes the SHA-256 hash of the file contents.
- It copies the file with a fingerprinted name:
{stem}.{hash}.{ext}. - A manifest maps original paths to fingerprinted paths.
- The
| fingerprinttemplate filter resolves paths via this manifest during page rendering.
Original files are kept alongside fingerprinted copies so that external links and bookmarks continue to work.
Template Filter
Basic Usage
The | fingerprint filter takes an asset path and returns the fingerprinted equivalent:
<link rel="stylesheet" href="/{{ 'theme/assets/css/style.css' | fingerprint }}">
{# Renders: /theme/assets/css/style.a1b2c3d4e5.css #}
<script src="/{{ 'theme/assets/js/app.js' | fingerprint }}"></script>
{# Renders: /theme/assets/js/app.deadbeef01.js #}
If the path is not in the manifest (e.g., the file was excluded or fingerprinting is disabled), the filter returns the path unchanged. This means templates work correctly in both fingerprinted and non-fingerprinted builds.
Subresource Integrity (SRI)
Pass integrity=true to get an object with .url and .integrity attributes:
{% set css = 'theme/assets/css/style.css' | fingerprint(integrity=true) %}
<link rel="stylesheet"
href="/{{ css.url }}"
integrity="{{ css.integrity }}"
crossorigin="anonymous">
The .integrity value is a base64-encoded hash in SRI format (e.g., sha256-abc123...), suitable for the HTML integrity attribute. Browsers will verify the file contents match the hash before applying the stylesheet or executing the script.
Serve Mode
In accent serve mode, the | fingerprint filter is a no-op: it returns the original path unchanged. This is correct because serve mode compiles styles on-the-fly and serves assets from disk without renaming.
Configuration
All settings are under build.fingerprint in config.yaml:
build: fingerprint: enabled: true # Default: false (opt-in) algorithm: sha256 # sha256, sha384, or sha512 length: 10 # Hex characters in the filename hash include: # Glob patterns to fingerprint - "**/*.css" - "**/*.js" exclude: # Glob patterns to skip - "**/*.map"
Settings Reference
| Setting | Default | Description |
|---|---|---|
enabled | false | Enable asset fingerprinting. Opt-in to avoid breaking existing themes. |
algorithm | sha256 | Hash algorithm: sha256, sha384, or sha512. |
length | 10 | Number of hex characters from the hash to use in filenames. |
include | ["**/*.css", "**/*.js"] | Glob patterns for files to fingerprint. |
exclude | ["**/*.map"] | Glob patterns for files to skip. |
Including Additional File Types
To fingerprint fonts and images as well:
build: fingerprint: enabled: true include: - "**/*.css" - "**/*.js" - "**/*.woff2" - "**/*.svg"
CDN Cache Headers
When fingerprinted assets are deployed behind a CDN, set long-lived cache headers:
Cache-Control: public, max-age=31536000, immutable
This tells browsers and CDNs to cache the file for one year without revalidation. Since the filename changes when the content changes, stale copies are never served.
Accent CMS already sets immutable cache headers for CSS/JS assets in accent serve --production . For static deployments, configure these headers in your hosting platform:
- Cloudflare Pages: Automatic for static assets
- Netlify: Add a
_headersfile with rules fortheme/assets/* - nginx:
location /theme/assets/ { expires 1y; add_header Cache-Control "public, immutable"; }
Edition Availability
Asset fingerprinting is available in all editions, including the free Core edition. No license key is required.