Radical
Explanation

Offline caching

Why snapshots require an online visit and an exact URL.

Remote snapshots preserve successful documents, not arbitrary application data. An online visit must store a route before that exact URL can work offline.

Service worker assets and exact-URL snapshots
flowchart TD
  Build[Build ID and asset manifest] --> Install[Worker install: precache assets and offline.html]
  Install --> Activate[Activate: delete older app cache namespaces]
  Activate --> Nav[Same-origin GET document navigation]
  Nav --> Network{Network request}
  Network -->|Response| Eligible{Successful, non-redirected HTML with x-radical-offline: 1?}
  Eligible -->|Yes| Cache[Store snapshot with exact URL and query]
  Cache --> Return[Return network response]
  Eligible -->|No| Return
  Network -->|Request rejects| Match{Exact snapshot exists?}
  Match -->|Yes| HTML[Return stored HTML]
  Match -->|No| Fallback[Return cached offline.html or Response.error]
  Cache --> Check[Shell checks completed snapshot for current URL]
  Check -->|Confirmed message| Saved[Persist saved snapshot URL]

A /reports?page=1 snapshot cannot satisfy /reports?page=2. HTTP error responses do not trigger the network-rejection fallback. Storage failures do not discard a successful network response.

Native startup adds recovery

Remote shell startup recovery
flowchart TD
  subgraph Android
    Start[Android launch gate] --> Connected{Internet capability present?}
    Connected -->|Yes| Config[Select configured URL]
    Connected -->|No| Saved{Allowed saved app URL?}
    Saved -->|Yes| Select[Select saved URL]
    Saved -->|No| Config
    Config --> Gate{Service worker API available?}
    Select --> Gate
    Gate -->|Yes| Lookup[Wait for getRegistration: fulfillment or rejection]
    Gate -->|No| Load[Load selected URL]
    Lookup --> Load
    Load --> Outcome{Navigation outcome}
    Outcome -->|Network or snapshot response| Ready[Show document]
    Outcome -->|Worker fallback response| WebFallback[Show worker offline.html]
    Outcome -->|Main-frame load error| NativeFallback[Show packaged offline HTML]
  end
  subgraph iOS
    Initial[Load configured URL] --> Result{Navigation outcome}
    Result -->|Network or snapshot response| Document[Show document]
    Result -->|Worker fallback header| Header[Recovery requested by response]
    Result -->|Load failure| Error[Recovery requested by load error]
    Header --> Launching{Still launching?}
    Error --> Launching
    Launching -->|Yes| Attempted{Snapshot already attempted?}
    Attempted -->|No| Exists{Saved URL exists and parses?}
    Exists -->|Yes| Allowed{Saved origin allowed?}
    Allowed -->|Yes| Distinct{Saved URL differs from current URL?}
    Distinct -->|Yes| Retry[Mark attempted and load saved URL once]
    Retry --> Result
    Launching -->|No| Reason{Recovery trigger}
    Attempted -->|Yes| Reason
    Exists -->|No| Reason
    Allowed -->|No| Reason
    Distinct -->|No| Reason
    Reason -->|Worker fallback header| WorkerHTML[Allow worker offline.html]
    Reason -->|Load failure| Packaged[Load packaged offline HTML]
  end

The iOS flow covers allowed main-frame startup navigations. Recovery cancellation callbacks are consumed; unrelated cancellations go to Capacitor.

Android stores lastOfflineUrl; iOS stores radical.lastOfflineURL. The saved URL records a confirmed snapshot; it does not contain HTML. Clearing web data deletes snapshots and worker registrations, so a saved URL cannot restore deleted data. Bundled mode omits this recovery path.

Cache boundaries

BoundaryConsequence
Known assets and same-origin GET navigationsArbitrary API responses are not cached
Content-derived build IDActivation removes older app cache namespaces
HTML snapshotsUser data may remain locally; sign-out needs a deletion policy
iOS App-Bound DomainsAt most ten distinct configured hostnames
Recorded WebKit experimentThree worker origins; prefer one stable app origin

The iOS caching decision records the platform evidence. Keep visited routes available offline contains setup; Data protection describes deletion.

On this page