Skip to content

build: content-hashed asset copies + asset-manifest.json - #688

Merged
Randy808 merged 4 commits into
Blockstream:ci-github-actionsfrom
DeviaVir:content-hashed-assets
Oct 6, 2026
Merged

Randy808 merged 4 commits into
Blockstream:ci-github-actionsfrom
DeviaVir:content-hashed-assets

Conversation

@DeviaVir

@DeviaVir DeviaVir commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

The static assets are not content-hashed (app.js, style.css, ...), so any
cache in front of the explorer has to choose between long TTLs (deploys
take hours to show up, and new HTML can load old JS/CSS) and frequent
revalidation.

The build now writes content-hashed copies (sha256, 12 hex) of app.js,
style.css, style-rtl.css, instascan.min.js, js/infinite-scroll.js and the
fonts referenced from the CSS, keeps the original files, and writes
asset-manifest.json. index.html, notfound.html and the prerender server
reference the hashed names, so deployments can serve hashed files with
Cache-Control: public, max-age=31536000, immutable and keep only the HTML
short-lived. The stylesheet link carries data-ltr/data-rtl so the Hebrew
switch picks the hashed RTL file (HTML cached before this change still
works). Fonts are rewritten inside the CSS before the CSS is hashed.
HASH_ASSETS=0 restores the old names (no manifest, no copies).

Also fixes two absolute paths that broke when the explorer is served under
a prefix: lander.js loaded ${staticRoot}/js/infinite-scroll.js (double
slash) and style.css used url('/img/icons/arrow-right-orange.svg').

@DeviaVir
DeviaVir requested review from Randy808 and a balanced review from Copilot and removed request for Randy808 October 6, 2026 08:48
@DeviaVir
DeviaVir marked this pull request as ready for review October 6, 2026 08:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The bundled prerender service cannot locate the flavor-specific manifest, so /nojs/ pages still reference unhashed assets.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds content-hashed frontend assets and manifest-based URL resolution for improved caching.

Changes:

  • Generates hashed scripts, stylesheets, and fonts with asset-manifest.json.
  • Updates templates and lazy loaders to use hashed paths.
  • Adds tests, documentation, and prefix-safe asset URLs.
File Description
www/​style.css Makes the icon URL prefix-safe.
test/​hash-assets.test.js Tests hashing, manifests, and templates.
scripts/​hash-assets.js Generates hashed asset copies and manifest.
scripts/​asset-manifest.js Loads manifests with fallback behavior.
render-view.js Supplies the manifest when rendering errors.
README.md Documents hashed-asset deployment.
prerender-server/​src/​server.js Supplies manifests to prerendered pages.
client/​src/​views/​lander.js Uses the hashed infinite-scroll script.
client/​src/​driver/​instascan.js Uses the hashed scanner script.
client/​src/​app.js Switches between resolved LTR/RTL stylesheets.
client/​index.pug Renders manifest-resolved asset URLs.
build.sh Integrates hashing into the build pipeline.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread prerender-server/src/server.js Outdated
@DeviaVir
DeviaVir changed the base branch from master to ci-github-actions October 6, 2026 09:08
The static assets are not content-hashed (app.js, style.css, ...), so any
cache in front of the explorer has to choose between long TTLs (deploys
take hours to show up, and new HTML can load old JS/CSS) and frequent
revalidation.

The build now writes content-hashed copies (sha256, 12 hex) of app.js,
style.css, style-rtl.css, instascan.min.js, js/infinite-scroll.js and the
fonts referenced from the CSS, keeps the original files, and writes
asset-manifest.json. index.html, notfound.html and the prerender server
reference the hashed names, so deployments can serve hashed files with
`Cache-Control: public, max-age=31536000, immutable` and keep only the HTML
short-lived. The stylesheet link carries data-ltr/data-rtl so the Hebrew
switch picks the hashed RTL file (HTML cached before this change still
works). Fonts are rewritten inside the CSS before the CSS is hashed.
HASH_ASSETS=0 restores the old names (no manifest, no copies).

Also fixes two absolute paths that broke when the explorer is served under
a prefix: lander.js loaded `${staticRoot}/js/infinite-scroll.js` (double
slash) and style.css used url('/img/icons/arrow-right-orange.svg').
The Docker image builds each flavor into /srv/explorer/static/<flavor>, so the
default manifest path (dist/asset-manifest.json) did not exist for the bundled
prerender service and /nojs/ pages kept the unhashed asset names.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Prerendered landing pages still reference the unhashed infinite-scroll script.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (1)

Comment thread client/src/views/lander.js Outdated
The prerender bundle is compiled before the static builds, so envify cannot
bake the hashed infinite-scroll name into it, and lander.js read the env var
once at module load. The prerender server now loads the flavor's manifest
once at startup and exports the lazy-script names (exportAssetEnv), and
lander.js reads the name at render time. The browser bundle is unchanged:
envify still inlines the literal.
@Randy808
Randy808 merged commit 083b4c2 into Blockstream:ci-github-actions Oct 6, 2026
3 checks passed
@DeviaVir
DeviaVir deleted the content-hashed-assets branch October 6, 2026 15:07
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.

3 participants