# Cookie Consent on Single-Page Apps: The Route Change That Drops Consent

Source: https://consentfort.com/blog/2026-11-15-cookie-consent-single-page-apps-route-change.html

*A single-page app loads once and then never reloads. The visitor clicks from the home page to the product page to checkout, and the browser never fetches a new document. The consent banner, which was built for a site that reloads on every navigation, appears once, records the choice, and never appears again. The scripts that load on the second route, the third-party widget on the product page, the analytics on checkout, never get a consent check, because the check only runs on page load, and the page only loaded once. The consent state is stale from the first route change, and nobody notices, because the banner is gone and the CMP says the visitor consented.*

## The banner runs once, the app runs forever

Most CMPs were built for multi-page sites. They check consent on page load, block scripts that lack it, and show the banner if no choice is stored. On a single-page app, page load happens once, at the first visit. Every navigation after that is a JavaScript route change: the URL changes, the content changes, and the CMP does nothing, because nothing told it a new page loaded. A third-party script that is supposed to be blocked until consent loads on the second route, because the router mounted it and the CMP never saw it. A vendor that was added to the product page after the consent choice was recorded starts collecting data under a choice that was made before the vendor existed. The EDPB's Guidelines 05/2020 require consent to be specific to the purposes and the processing, and a choice made before the processing existed cannot cover it.

The fix is to hook the CMP into the router. Every route change has to re-run the consent check: which scripts does this route load, which of them need consent, and does the stored choice cover them. If a route loads a script that needs a purpose the visitor did not accept, the script stays blocked until the visitor changes their choice. If a route introduces a new vendor, the banner or the preferences panel has to surface it. The CNIL's guidance treats a change in processing as a reason to re-ask, and a new vendor on a new route is a change in processing, whether or not the page reloaded.

## Test it by navigating, not by reloading

Clear your cookies, load the app, accept only necessary cookies, and then navigate to the product page and to checkout without reloading. Open the network tab and watch what loads on each route. If a marketing script appears on the product page after you refused marketing, the router loaded it without a consent check. If an analytics call fires on checkout after you refused analytics, the same failure happened there. [The consent proof post covers the record side of this](https://consentfort.com/blog/2026-11-13-consent-proof-export-audit-trail.md): the record that makes the banner worth something is the record that shows what the visitor actually agreed to, and on a single-page app the record has to show the choice per route, not just the first page. [CMP migration has the same staleness problem](https://consentfort.com/blog/2026-11-11-cmp-migration-consent-reset-opt-in-cost.md): a consent reset that costs half the opt-ins, because the stored choices do not survive the move to a new system, and the single-page app is the same failure in a different shape, choices that do not survive a route change.

## Log the route, not just the load

The consent log on a single-page app has to record route changes, not just page loads. When the visitor navigates, log the route, the scripts that route requested, and whether the stored choice allowed them. The log is the evidence that the consent check ran on every route, and it is the evidence a regulator asks for when the banner only ever appeared once. A log with one entry for a ten-route session is a log that proves the check did not run. A log with ten entries is a log that proves it did.

Do not rely on the CMP's default single-page support. Test it the way the visitor uses it: navigate, do not reload, and watch the network tab. The route change is where consent goes stale, and the stale consent is the one the CMP reports as valid.

## Frequently asked questions

### Why is consent different on a single-page app?

Because the page only loads once. Most CMPs check consent on page load, so on a single-page app the check runs on the first visit and never again. Route changes load new scripts without a consent check, and the stored choice goes stale from the first navigation.

### How do I fix consent on a single-page app?

Hook the CMP into the router so every route change re-runs the consent check. Each route should verify which scripts it loads, whether the stored choice covers them, and block any script that needs a purpose the visitor did not accept. A new vendor on a new route has to surface in the banner or the preferences panel.

### How do I test consent on a single-page app?

Clear cookies, accept only necessary cookies, then navigate through the app without reloading and watch the network tab. If a marketing script loads on the product page after you refused marketing, the router loaded it without a check. Test by navigating, not by reloading.

### What should the consent log record on a single-page app?

Every route change, not just the page load: the route, the scripts it requested, and whether the stored choice allowed them. A log with one entry for a ten-route session proves the check did not run. A log with an entry per route proves it did.
