Skip to content

Add content hashes to asset URLs#6749

Open
harsh21234i wants to merge 3 commits into
reflex-dev:mainfrom
harsh21234i:fix/asset-content-hash-6550
Open

Add content hashes to asset URLs#6749
harsh21234i wants to merge 3 commits into
reflex-dev:mainfrom
harsh21234i:fix/asset-content-hash-6550

Conversation

@harsh21234i

Copy link
Copy Markdown
Contributor

Closes #6550.

Adds content-hash cache busting to rx.asset URLs by appending an 8-character SHA-256 query parameter based on the
asset file contents.

Example:
rx.asset("logo.svg") now returns /logo.svg?v=<hash>.

The hash changes only when the file content changes, allowing browsers to cache assets safely across deploys.

Implementation notes:

  • Applies to both local and shared assets.
  • Keeps AssetPathStr.importable_path unversioned so existing build-time import behavior is preserved.
  • Preserves backend-only behavior for missing local assets.
  • Adds regression coverage for hash changes and pickle/copy round trips.

@harsh21234i harsh21234i requested review from a team and Alek99 as code owners July 11, 2026 06:15
@greptile-apps

greptile-apps Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds content-hash cache busting to asset URLs. The main changes are:

  • Appends an eight-character SHA-256 query parameter to local and shared asset URLs.
  • Reads asset files in chunks and retries when a file changes during hashing.
  • Keeps build-time import paths free of the version query.
  • Preserves versioned paths through pickle and copy operations.
  • Documents and tests the new behavior.

Confidence Score: 4/5

The remaining cache race should be fixed before merging.

  • Chunked hashing avoids loading entire assets into memory.
  • Retries handle changes that occur while a file is being read.
  • A change between hashing and the later frontend copy can still deploy new bytes under an old cache key.

reflex/assets.py

Important Files Changed

Filename Overview
reflex/assets.py Adds chunked content hashing, change detection, versioned asset paths, and serialization support; hashing can still diverge from the later build copy.
tests/units/assets/test_assets.py Covers content changes, chunked reads, transient concurrent modification, import paths, and serialization round trips.
docs/assets/overview.md Documents content-hash query parameters for asset URLs.
news/6550.feature.md Adds a release note for content-hash cache busting.

Reviews (3): Last reviewed commit: "Merge branch 'main' into fix/asset-conte..." | Re-trigger Greptile

Comment thread reflex/assets.py Outdated
Comment thread reflex/assets.py
@codspeed-hq

codspeed-hq Bot commented Jul 11, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing harsh21234i:fix/asset-content-hash-6550 (9953842) with main (11f8a7a)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Comment thread reflex/assets.py
Comment on lines +154 to +155
"""
versioned_path = f"{relative_path}?v={_short_content_hash(source_file)}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Hash Can Precede Copy — The stability check only covers the time spent reading source_file. The assets directory is copied into the frontend build later. If a generated asset changes after this hash is calculated but before that copy, the page keeps the old ?v= value while the public directory receives new bytes. Browsers may then reuse a cached response instead of fetching the deployed file. Hashing and copying need to use the same immutable snapshot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rx.asset: add content-hash cache-busting to returned URL

1 participant