Revalidating cache on app assets; site title survives SPA navigation
Test / test (push) Successful in 24s
Test / test (push) Successful in 24s
pkg files keep stable names across releases, so an uncontrolled browser cache could pair last release's wasm with the new server's server-fn wire format - every page then renders its error branch (redoal.com's 'Nothing here' after v0.2.0). Cache-Control: no-cache on /pkg and /yes.js makes clients revalidate (a 304 per load) instead of guessing. The content-declared site title also moves out of the question Suspense: remounting with each navigation lost the leptos_meta race to the compile-time fallback, flipping redoal.com's tab to 'uhhm' on the first client-side nav. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c67f6f1a59
commit
a0305282ef
+1
-1
@@ -19,7 +19,7 @@ axum = { version = "0.8", features = ["multipart"], optional = true }
|
|||||||
aws-sdk-s3 = { version = "1", optional = true }
|
aws-sdk-s3 = { version = "1", optional = true }
|
||||||
tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal"], optional = true }
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal"], optional = true }
|
||||||
tower = { version = "0.5", optional = true }
|
tower = { version = "0.5", optional = true }
|
||||||
tower-http = { version = "0.6", features = ["fs"], optional = true }
|
tower-http = { version = "0.6", features = ["fs", "set-header"], optional = true }
|
||||||
tower-sessions = { version = "0.14", optional = true }
|
tower-sessions = { version = "0.14", optional = true }
|
||||||
async-nats = { version = "0.38", optional = true }
|
async-nats = { version = "0.38", optional = true }
|
||||||
arc-swap = { version = "1", optional = true }
|
arc-swap = { version = "1", optional = true }
|
||||||
|
|||||||
+12
-7
@@ -89,6 +89,18 @@ fn QuestionPage() -> impl IntoView {
|
|||||||
let site = Resource::new(|| (), |_| get_site());
|
let site = Resource::new(|| (), |_| get_site());
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
// The content-declared site title lives OUTSIDE the question
|
||||||
|
// Suspense: tied to the per-page resource it unmounted on every
|
||||||
|
// SPA navigation and lost the leptos_meta race to App's
|
||||||
|
// compile-time SITE_NAME fallback (redoal.com flashing to
|
||||||
|
// "uhhm" on nav - and staying there). Out here it mounts once
|
||||||
|
// and covers every branch, NotFound included.
|
||||||
|
{move || {
|
||||||
|
site.get()
|
||||||
|
.and_then(|r| r.ok())
|
||||||
|
.and_then(|s| s.title)
|
||||||
|
.map(|t| view! { <Title text=t/> })
|
||||||
|
}}
|
||||||
<Suspense fallback=|| {
|
<Suspense fallback=|| {
|
||||||
view! {
|
view! {
|
||||||
<main class="loading">
|
<main class="loading">
|
||||||
@@ -109,13 +121,6 @@ fn QuestionPage() -> impl IntoView {
|
|||||||
Ok(Some(page)) => {
|
Ok(Some(page)) => {
|
||||||
let current = user_res.and_then(|r| r.ok()).flatten();
|
let current = user_res.and_then(|r| r.ok()).flatten();
|
||||||
view! {
|
view! {
|
||||||
// A second <Title> outranks App's
|
|
||||||
// SITE_NAME fallback only when content
|
|
||||||
// actually declares one.
|
|
||||||
{site_cfg
|
|
||||||
.title
|
|
||||||
.clone()
|
|
||||||
.map(|t| view! { <Title text=t/> })}
|
|
||||||
<QuestionView
|
<QuestionView
|
||||||
question=page.question
|
question=page.question
|
||||||
chain_gate=page.chain_gate
|
chain_gate=page.chain_gate
|
||||||
|
|||||||
+27
-2
@@ -143,7 +143,22 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.route("/upload", post(upload::upload))
|
.route("/upload", post(upload::upload))
|
||||||
.route("/gitea-repo", get(content::gitea_repo_handler))
|
.route("/gitea-repo", get(content::gitea_repo_handler))
|
||||||
.route("/automation/kv/{bucket}", get(content::automation_kv_handler))
|
.route("/automation/kv/{bucket}", get(content::automation_kv_handler))
|
||||||
.nest_service("/pkg", ServeDir::new(pkg_dir))
|
// no-cache = "revalidate before reuse", not "don't cache":
|
||||||
|
// pkg files keep the same names across releases (portal.js,
|
||||||
|
// portal.wasm), and without this browsers heuristically cache
|
||||||
|
// them - a stale wasm from the previous release then talks to
|
||||||
|
// a server whose server-fn wire format has moved on and every
|
||||||
|
// page renders as its error branch. A 304 per load is the
|
||||||
|
// price of never shipping that skew again.
|
||||||
|
.nest_service(
|
||||||
|
"/pkg",
|
||||||
|
tower::ServiceBuilder::new()
|
||||||
|
.layer(tower_http::set_header::SetResponseHeaderLayer::overriding(
|
||||||
|
axum::http::header::CACHE_CONTROL,
|
||||||
|
axum::http::HeaderValue::from_static("no-cache"),
|
||||||
|
))
|
||||||
|
.service(ServeDir::new(pkg_dir)),
|
||||||
|
)
|
||||||
.nest_service("/fonts", ServeDir::new(fonts_dir))
|
.nest_service("/fonts", ServeDir::new(fonts_dir))
|
||||||
.route_service("/favicon-light.svg", ServeFile::new(favicon_light_path))
|
.route_service("/favicon-light.svg", ServeFile::new(favicon_light_path))
|
||||||
.route_service("/favicon-dark.svg", ServeFile::new(favicon_dark_path))
|
.route_service("/favicon-dark.svg", ServeFile::new(favicon_dark_path))
|
||||||
@@ -152,7 +167,17 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
"/swiper-element-bundle.min.js",
|
"/swiper-element-bundle.min.js",
|
||||||
ServeFile::new(swiper_path),
|
ServeFile::new(swiper_path),
|
||||||
)
|
)
|
||||||
.route_service("/yes.js", ServeFile::new(yes_path))
|
// Same skew concern as /pkg: the wasm's raw_module import and
|
||||||
|
// the hero's inline script both load this by fixed name.
|
||||||
|
.route_service(
|
||||||
|
"/yes.js",
|
||||||
|
tower::ServiceBuilder::new()
|
||||||
|
.layer(tower_http::set_header::SetResponseHeaderLayer::overriding(
|
||||||
|
axum::http::header::CACHE_CONTROL,
|
||||||
|
axum::http::HeaderValue::from_static("no-cache"),
|
||||||
|
))
|
||||||
|
.service(ServeFile::new(yes_path)),
|
||||||
|
)
|
||||||
.leptos_routes_with_context(
|
.leptos_routes_with_context(
|
||||||
&state,
|
&state,
|
||||||
routes,
|
routes,
|
||||||
|
|||||||
Reference in New Issue
Block a user