Single-page apps
Next.js, React, Vue and other client-side routers need no extra setup. What Optimeleon does when the page changes without a full reload, and the few things to plan around.
On a single-page app the browser loads one document, and your app swaps the content as the visitor moves around. Optimeleon follows those navigations on its own. There is nothing to switch on and nothing to call: every route gets the right version, and every route is tracked.
It follows each route change your app makes through the browser's history, which is how the routers in Next.js, React Router, Vue, Nuxt, SvelteKit and Angular work, plus the back and forward buttons. A URL changed some other way is picked up a moment later.
Install it in the page your server sends
The snippet goes in the <head> of the HTML your server returns, as high as you can put it and exactly as the app gives it, the same as on any other site. In most frameworks that is the root layout or the document template.
For steps written for your framework, open Custom instructions on the script step in Setup. The AI Installation Kit detects your stack and writes them for it.
What happens on each navigation
- Optimeleon checks whether the new page is part of a campaign.
- If it is, it applies that visitor's version of the page. A page they already opened in this tab shows its version instantly.
- If it is not, it removes the previous page's changes, so the visitor sees your original content.
While a version is swapped in, only the elements being changed are hidden, and only briefly. The rest of the page stays on screen. If the version for a page cannot be fetched in time, that page shows your original version, and nothing on it breaks.
The list of pages with a campaign is read when the page first loads, so a campaign you start while someone is browsing reaches them on their next full page load.
# are ignored, so /pricing?plan=pro is the same page as /pricing. If your app routes with URLs like /#/pricing, every route is the same page to Optimeleon, and a campaign on it runs on all of them. Give the pages you want to optimize their own paths.When your app re-renders
If your framework re-renders part of the page Optimeleon changed, Optimeleon puts its change back. Content that appears late, after the route has rendered, is changed when it arrives.
On a server-rendered site, the first page waits for your framework to finish hydrating before anything is changed, so hydration sees exactly the HTML your server sent. If your framework hydrates unusually late, you may occasionally see a hydration warning in the browser console. The variant is re-applied and stays in place.
Tracking
- A page view is recorded for every route change once the visitor has consented. There is nothing to call. Jumping to an anchor on the same page, such as
#reviews, is not a new page view. - Fire conversions the same way as on any site, from whichever route they happen on. They count for the version the visitor saw, even when the conversion happens on a route that is not part of a campaign.
- Using a tag manager? Never fire Optimeleon from a History Change trigger. See Google Tag Manager.
Consent
Consent carries across route changes. Your cookie banner passes the visitor's choice on each full page load, as described in Consent & cookies, but not again after each navigation inside the app.
To make going back instant, Optimeleon remembers the version of each page already opened in the tab. Before consent that is held in memory only. After consent it is kept in the tab's session storage as __opti_route_cache*, which is in the storage reference, and it is cleared when the tab closes or consent is withdrawn.
Event hooks on route changes
variant.decided and variant.applied fire again each time the visitor moves to another page that is being optimized, so a subscriber can follow the navigation without polling. ready, page.revealed and consent.resolved fire once per full page load. See Event hooks.
