Caching

Set Cache-Control headers on #[load] responses to cache server data at the edge or in the browser.

LIVE

Cache-Control on #[load]

SSR loader value: Cached loader response

SSR loaded at: unix:1784086644

Loader policy
#[load(cache = "public, max-age=60")]
Response Cache-Control
Server stamp (now)

Refresh headers fetches this page with cache: no-store. SPA reload uses invalidate() to bust prefetch and re-run #[load] — watch the SSR timestamp above change.

cache attribute

#[load(cache = "public, max-age=60")]
async fn home(_req: &FlowRequest) -> HomeData {
    HomeData { title: "Welcome".into() }
}

#[load(cache = "public, max-age=120")]
async fn docs_index(_req: &FlowRequest) -> DocsData {
    fetch_docs().await
}

How it works

When a page calls a cached loader, Resuma merges its cache hint into the HTML response Cache-Control header. Use short max-age for frequently changing data, longer for static-ish content.

Interactive apps (forms, CSRF cookie) override public caching to private, no-store on the HTML response — see the live demo above. The loader attribute still documents intent and applies on routes without session cookies.

Private caching

#[load(cache = "private, max-age=300")]
async fn dashboard(req: &FlowRequest) -> DashData {
    user_dashboard(req).await
}

When not to cache

Omit the cache attribute for personalized or auth-gated loaders. Default behavior sends no Cache-Control override.