Files
next.js/docs/01-app/03-api-reference/05-config/01-next-config-js/outputHashSalt.mdx
3e0158846e feat: add NEXT_HASH_SALT env var for content-hash filename salting (#91871)
### What?

Adds a `NEXT_HASH_SALT` environment variable **and** a
`experimental.outputHashSalt` config option that mix a user-supplied
string into every content-addressed hash used to generate chunk
filenames and static asset filenames. This works for both Webpack and
Turbopack.

When both are set, the values are concatenated (`outputHashSalt +
NEXT_HASH_SALT`), so a per-project salt can be baked into
`next.config.js` while a per-deployment salt is injected at build time
via the environment variable.

### Why?

Content-addressed filenames (e.g. `chunk.abc123.js`) are derived from
file content, so they only change when the content changes. There are
deployment scenarios where you need to force all filenames to rotate —
for example after a CDN misconfiguration has poisoned caches for a
particular hash space — without actually changing source code. A stable,
opt-in salt lets operators do this without touching application code.

Some customers prefer the config-file approach
(`turbopack.outputHashSalt`) over environment variables, so both are
supported.

### How?

**Webpack** already has `output.hashSalt` in its config. We simply
forward `NEXT_HASH_SALT` to that option.

**Turbopack** required threading the value through several layers:

1. The effective hash salt is computed once in
`assignDefaultsAndValidate` as `config.turbopackHashSalt =
(turbopack.outputHashSalt ?? '') + (NEXT_HASH_SALT ?? '')` and stored on
`NextConfigComplete`. Both `turbopackBuild` (production) and
`createHotReloaderTurbopack` (dev) read from this single field.
2. `ProjectOptions.hash_salt` receives the pre-computed salt.
3. `Project` stores the salt and passes it into the three chunking
context option structs (`ClientChunkingContextOptions`,
`ServerChunkingContextOptions`, `EdgeChunkingContextOptions`).
4. Both `BrowserChunkingContext` and `NodeJsChunkingContext` gain a
`hash_salt: RcStr` field.
5. A new `deterministic_hash_with_salt(salt, input, algorithm)` function
in `turbo-tasks-hash` writes the salt bytes first, then the content
bytes, into a single hasher — one pass, no hash-of-hash composition.
6. A matching `content_hash_with_salt` method is added to `FileContent`
and `AssetContent`.
7. `ChunkingContext::asset_path` is changed to accept `Vc<AssetContent>`
(instead of a pre-computed `Vc<RcStr>`) so the chunking context can
choose the correct hash path itself. `StaticOutputAsset::path`
simplifies accordingly.

Without `NEXT_HASH_SALT` and without `turbopack.outputHashSalt` set,
behaviour is identical to before — no hash change, no performance
impact.

**e2e test** (`test/production/app-dir/hash-salt/`) verifies:
- Two builds with the same salt produce identical chunk and static asset
filenames.
- A build with a different salt produces different filenames.
- `turbopack.outputHashSalt` (config) changes filenames vs no salt.
- Combined config + env salt differs from either alone.
- Runs for both Turbopack and Webpack.

---------

Co-authored-by: Tobias Koppers <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Luke Sandberg <[email protected]>
2026-04-01 22:03:50 +02:00

35 lines
1.4 KiB
Plaintext

---
title: outputHashSalt
description: Learn how to incorporate a custom salt string into content-addressed output filenames.
version: experimental
---
`outputHashSalt` is an experimental option that incorporates a configurable salt string into every content-addressed output filename (chunks, assets). Changing this value forces all output hashes to change, which is useful for invalidating cached assets across deployments without modifying source files.
To configure the output hash salt, set `experimental.outputHashSalt` in `next.config.js`:
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
outputHashSalt: 'my-deployment-salt',
},
}
module.exports = nextConfig
```
This works with both Webpack and Turbopack bundlers.
The `NEXT_HASH_SALT` environment variable can also be used for the same purpose. When both are set, the values are **concatenated** (`experimental.outputHashSalt + NEXT_HASH_SALT`) to form the effective salt. This lets you combine a per-project salt baked into the config with a per-deployment salt injected at build time via environment variable.
```bash filename="Terminal"
NEXT_HASH_SALT=my-deployment-salt next build
```
## Version History
| Version | Changes |
| -------- | ---------------------------------------- |
| `16.3.0` | `experimental.outputHashSalt` was added. |