Astro Info
Astro v7.0.9
Vite v8.1.4
Node v24.18.0
System Windows (x64)
Package Manager npm
Output static
Adapter none
Integrations none
Describe the Bug
Font files from the local provider are emitted to /_astro/fonts/<hash>.<ext>, where the hash input is the font's absolute filesystem path + content, not content alone:
// fs-font-file-content-resolver.ts
resolve(url: string): string {
if (!isAbsolute(url)) {
return url;
}
// ...
return url + this.#readFileSync(url);
}
// build-font-file-id-generator.ts
generate({ originalUrl, type }) {
return `${this.#hasher.hashString(this.#contentResolver.resolve(originalUrl))}.${type}`;
}
So the same commit emits a different font URL depending on where the project is checked out. All other bundled assets (CSS, JS, images) hash by content only.
This bit me while verifying a deploy: my local build emitted 1e7f9644fd95bd74.woff2, Cloudflare Workers Builds emitted 276137e118374bb0.woff2 from the same commit, so the URL predicted from the local build 404'd in production. It also means CI systems with per-build workspace paths bust the font cache on every deploy even when the bytes haven't changed.
The path inclusion looks deliberate (the comment in resolve() mentions rename/swap correctness), but that concern is about the internal cache key — the emitted filename could hash content only without affecting it.
What's the expected result?
Building the same project from two different directories emits the same /_astro/fonts/ filenames.
Link to Minimal Reproducible Example
https://github.com/AdamLMark/astro-font-hash-repro
Clone into two directories, npm install && npm run build in each, compare dist/_astro/fonts/: 1e84ced4522bd42f.woff2 vs dff6f0b9a6f55b9f.woff2.
Astro Info
Describe the Bug
Font files from the local provider are emitted to
/_astro/fonts/<hash>.<ext>, where the hash input is the font's absolute filesystem path + content, not content alone:So the same commit emits a different font URL depending on where the project is checked out. All other bundled assets (CSS, JS, images) hash by content only.
This bit me while verifying a deploy: my local build emitted
1e7f9644fd95bd74.woff2, Cloudflare Workers Builds emitted276137e118374bb0.woff2from the same commit, so the URL predicted from the local build 404'd in production. It also means CI systems with per-build workspace paths bust the font cache on every deploy even when the bytes haven't changed.The path inclusion looks deliberate (the comment in
resolve()mentions rename/swap correctness), but that concern is about the internal cache key — the emitted filename could hash content only without affecting it.What's the expected result?
Building the same project from two different directories emits the same
/_astro/fonts/filenames.Link to Minimal Reproducible Example
https://github.com/AdamLMark/astro-font-hash-repro
Clone into two directories,
npm install && npm run buildin each, comparedist/_astro/fonts/:1e84ced4522bd42f.woff2vsdff6f0b9a6f55b9f.woff2.