Skip to content

Local provider font filenames are not deterministic — hash input includes the absolute file path #17377

Description

@AdamLMark

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P4: importantViolate documented behavior or significantly impacts performance (priority)pkg: astroRelated to the core `astro` package (scope)triage: fix verifiedReporter confirmed the triage bot fix works

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions