2 Commits
Author SHA1 Message Date
Bendik Aagaard Lynghaug d65c5593b3 Release 0.3.1
Test / test (push) Successful in 25s
Publish release / publish (push) Successful in 1m25s
2026-08-25 19:48:49 +02:00
Bendik Aagaard LynghaugandClaude Fable 5 330ab11fe9 Content-hashed pkg assets (hash-files) so stale bundles can't pair with new wasm
Test / test (push) Successful in 26s
An iPhone kept a heuristically-cached portal.js across three releases
(cached before Cache-Control: no-cache existed) and loaded it against
fresh wasm - its snippet imports 404'd, hydration never started, and
the gesture field never mounted. With hash-files = true every pkg
file is content-named and the freshly served page references exactly
its own bundle; hash.txt ships beside the binary (leptos resolves it
next to current_exe), the shell links the stylesheet through
HashedStylesheet, and instances set LEPTOS_HASH_FILES=true.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 19:48:47 +02:00
4 changed files with 16 additions and 5 deletions
+4 -1
View File
@@ -68,11 +68,14 @@ jobs:
stage=$(mktemp -d)
cp "$CARGO_TARGET_DIR/release/portal" "$stage/portal"
cp "$CARGO_TARGET_DIR/release/question_lint" "$stage/question_lint"
# hash-files = true: leptos resolves hash.txt next to the running
# binary, so it ships beside portal in the release dir.
cp "$CARGO_TARGET_DIR/release/hash.txt" "$stage/hash.txt"
# site-root ("target/site" in Cargo.toml) is project-relative,
# not affected by CARGO_TARGET_DIR - only the plain `cargo build`
# outputs (release/, front/) move with that override.
cp -r target/site "$stage/site"
tar -C "$stage" -czf "portal-$tag.tar.gz" portal question_lint site
tar -C "$stage" -czf "portal-$tag.tar.gz" portal question_lint hash.txt site
rm -rf "$stage"
# The run's own ephemeral token has write access to this repo -
Generated
+1 -1
View File
@@ -2948,7 +2948,7 @@ dependencies = [
[[package]]
name = "portal"
version = "0.3.0"
version = "0.3.1"
dependencies = [
"anyhow",
"arc-swap",
+7 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "portal"
version = "0.3.0"
version = "0.3.1"
edition = "2021"
[lib]
@@ -131,6 +131,12 @@ bin-default-features = false
lib-features = ["hydrate"]
lib-default-features = false
lib-profile-release = "wasm-release"
# Content-hashed pkg names (portal.<hash>.js/wasm/css) + hash.txt: a
# freshly served page can never reference a stale cached bundle - an
# iPhone kept a heuristically-cached portal.js across three releases
# and paired it with new wasm, silently killing hydration. Runtime
# needs LEPTOS_HASH_FILES=true (set in each content repo's deploy env).
hash-files = true
# cargo release <level> is how a portal version is cut: bump, commit,
# tag v{{version}}, push. CI (publish.yml) reacts to the tag and
+4 -2
View File
@@ -1,5 +1,5 @@
use leptos::prelude::*;
use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title};
use leptos_meta::{provide_meta_context, HashedStylesheet, MetaTags, Title};
use leptos_router::{
components::{Route, Router, Routes},
hooks::{use_location, use_navigate, use_query_map},
@@ -39,6 +39,9 @@ pub fn shell(options: LeptosOptions) -> impl IntoView {
// once loaded via <link>/<img> on Safari/iOS.
<link rel="icon" media="(prefers-color-scheme: light)" href="/favicon-light.svg" type="image/svg+xml"/>
<link rel="icon" media="(prefers-color-scheme: dark)" href="/favicon-dark.svg" type="image/svg+xml"/>
// Server-side, so it can read hash.txt and link the
// content-hashed stylesheet (hash-files = true).
<HashedStylesheet id="leptos" options=options.clone()/>
<AutoReload options=options.clone()/>
<HydrationScripts options/>
<MetaTags/>
@@ -67,7 +70,6 @@ pub fn App() -> impl IntoView {
provide_context(site);
view! {
<Stylesheet id="leptos" href="/pkg/portal.css"/>
<Suspense fallback=|| ()>
{move || {
site.get()