Excluding routes
Keep admin, checkout and logout routes on full navigation – centrally or per link.
Some pages shouldn't be swapped – an admin panel, a checkout, a logout route, anything that assumes a fresh page load. Opt them out and they fall back to ordinary full navigation.
Side-effect routes must not be GET
Sparke preloads by firing a real, credentialed
GET at reachable links while the browser is idle -
before any click. So a
GET /logout (or any GET that deletes,
unsubscribes, clears a cart, charges a card) gets hit
speculatively and runs on page load, logging your users out before
they touch anything. This is exactly why GET is
defined as a safe method: Chrome's prefetcher, antivirus
link scanners, and chat-app link unfurlers already break GET
logout for the same reason.
The real fix is to make the action a POST. Sparke
never preloads or intercepts non-GET forms, so it just works with
no exclusion needed:
<form method="post" action="/logout">
<button>Log out</button>
</form>
If the route must stay a GET link, exclude it with the mechanisms
below (data-ignore="/logout" or
rel="external"), or no-op it server-side
when the request carries the X-Sparke: preload header
- real clicks send X-Sparke: navigate instead, so you
can tell a speculative preload apart from a genuine logout.
Excluding a GET logout stops Sparke hitting it, but other
crawlers and prefetchers still will. POST is the
only fix that protects every client.
Centrally, on the script tag
Pass space-separated path patterns to data-ignore. A
trailing * is a prefix wildcard.
<script
src="sparke.min.js"
defer
data-ignore="/admin/* /checkout /logout"
></script>
/admin/* matches everything under
/admin/ but not the bare /admin –
list both to cover the root.
Per link
For one-off exclusions, use standard HTML – no Sparke API needed:
<a href="/legacy/billing" rel="external">Billing portal</a>
A whole page, Sparke-free
To make an entire page behave like a plain MPA page, simply omit
the <script> tag on it.