Appearance
Navigation
SPF navigation is a pipeline driven by the Navigation API. This page describes what happens from a click to the updated page.
The same pipeline at event level, and the response processing order, are covered in Events and Responses — this page details the Navigation API mechanics.
The pipeline
A navigation runs this sequence (the same order SPF used, modernized):
text
click .spf-link
→ spfclick (cancelable)
→ window.navigation.navigate(url, { history: 'push', state: { spf: true } })
→ navigate event intercepted
→ spfrequest (cancelable)
→ cache lookup (in-memory → durable Cache API)
→ fetch (single JSON or NDJSON stream) [see Streaming]
→ spfprocess (cancelable)
→ apply: title → url → head → attr → body → foot
→ spfdone- Click handling — left-clicks without modifier keys on an
spf-linkanchor or form are intercepted;spf-nolinkdescendants opt out. Thespfclickevent is dispatched synchronously ondocument— cancel it withpreventDefault()(or returnfalsefrom a handler registered withdocument.addEventListener) to let the browser navigate normally. - Interception — the
navigateevent is intercepted only for same-origin destinations that match the pending intent. Everything else is left to the browser. - Events — the pipeline events (
spfrequest,spfprocess,spfdone,spferror,spfpartprocess,spfpartdone) are Promise-aware: handlers registered withspf.event.on(name, fn)run before thedocumentCustomEvent of the same name, may be async, and are awaited in order; returningfalsecancels the step and falls back to a full browser navigation. The click-time events (spfclick,spfhistory,spfready,spfreload) are synchronous and skip the registry. See Events.
Processing order
The response is applied in SPF's order: title → url → head → attr → body → foot. head and foot HTML are installed into <head> (scripts execute in order and block unless async); attr sets attributes by element ID; body replaces each fragment's content by ID.
History navigation (back/forward)
Navigations with navigationType === 'traverse' to a page we recorded (state.spf) are handled by SPF:
spfhistoryfires (cancelable via the document event);- the response is served from cache — in-memory first, then the durable Cache API tier;
- on a cache miss the URL is fetched and stored.
This gives instant back/forward to previously visited SPF pages, bfcache-like, without a network round trip.
Back/forward to an entry without SPF state is left to the browser — except that a same-document destination would otherwise just rewind the URL and leave the SPF-replaced DOM stale, so SPF cancels the traversal and forces a full load of that URL instead (through the standard spfreload fallback). Cross-document destinations load the real page themselves.
Programmatic navigation
| Call | Effect |
|---|---|
spf.navigate(url) | Full SPF navigation; pushes a history entry. Resolves when settled. |
spf.load(url) | Fetches and applies a response without a URL change. |
spf.process(response) | Applies an already-fetched response to the current page. |
spf.prefetch(url) | Fetches into the cache for a later navigation; no DOM changes. |
All return Promises and accept a RequestOptions object (see Types).
Failure semantics
If the request fails, the response says reload: true, or a handler cancels the pipeline, SPF falls back to a full browser navigation:
spferrorfires with the error (when there is one);spfreloadfires with the target URL;location.assign(target)performs the full navigation.
If reload-identifier is configured (e.g. ?spf=full), the reason parameter is appended to the fallback URL so the server can distinguish full loads from SPF requests.
Note:
response.redirectalso falls back to a full navigation to the redirect target — the client intentionally does not follow redirects itself.