Open Tracked/Guides/Server side GTM for single page applications

Server side GTM for single page applications

In a single-page app the page never reloads, so you must send page views and events yourself. The server container then works as usual.

4 min read · Updated October 26, 2026

In this guide
Key takeaways
  • Single-page apps need virtual page views on route changes and events pushed when state is ready.
  • Make sure each event fires once, with fresh data, and carries an event ID.
  • The server side is unchanged: send events to your tagging subdomain.
RRoute change in the appEEvent pushed to data layerServer container forwards it

Sites built with React, Vue, Angular or Next.js often load once and then swap content without reloading. Tag Manager's default "page view" fires only on the first load. If nothing else is done, analytics sees one page view per visit and ad platforms miss most events. This page explains how to track a single-page app properly and what stays the same with a server container. See Meta Conversions API for a custom website and Google Tag Manager best practices.

Virtual page views

On every route change, push an event to the data layer with the new page path and title, and let a trigger on that event fire your page view tags. Do not rely on the History Change trigger alone; it can fire too often or too early.

// on every route change, after the new view has rendered
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: "virtual_page_view",
  page_path: location.pathname + location.search,
  page_title: document.title
});
Works worldwide

Runs on your domain, anywhere

Your tracking runs on your own domain, so a visit from any country is handled the same way.

Events and timing

  • Push events when the data is ready, not before. A purchase pushed before the order total is known will carry the wrong value.
  • Clear the ecommerce object before each push.
  • Fire once. A component that re-renders can fire a tag many times.
  • Include an event_id so the browser and server copies deduplicate. See event deduplication.

First load and referrer

The first page view should carry the original referrer and UTMs. On later route changes, do not overwrite them. Read the UTMs and click IDs on first load and store them in a first-party cookie, so that a later conversion in the same visit carries them. See avoiding UTM removal.

Check your setup

Check your tracking in one pass

This is an example. Run the check on your own site to see where yours stands.

Server-side differences: none, with two cautions

  • The server container receives the same requests. Point the Google tag to your tagging subdomain as for any site.
  • Server-side rendering (as in Next.js) can run code on the server and the browser. Make sure tracking code runs in the browser only, or send the event from the server deliberately and not twice.

Set the consent default before any tags load, and update it when the visitor chooses, as on any site. Because the app does not reload, make sure the update takes effect for subsequent events without a refresh. Test accept and reject without reloading.

Common problems

SymptomOnly one page view per visit
Likely causeNo virtual page views.
FixPush one per route change.
SymptomDuplicate events
Likely causeA component fires on every render.
FixGuard with state or a once-only check.
SymptomWrong values in events
Likely causePushed before data is ready.
FixPush after the data loads.
SymptomThe back button double counts
Likely causeThe route change fires twice.
FixDebounce or compare the previous path.
0 of 6 done
Live view

Watch events arrive, live

A sample feed. In Open Tracked you see the same stream for your own store.

Frequently asked questions

How do I track page views in a single-page app?

Push a virtual page view event to the data layer on every route change and trigger your page view tags on it.

Does server-side GTM work with single-page apps?

Yes. The server receives the same events. Point the Google tag to your tagging subdomain.

Why do I get duplicate events?

Components re-render and push again, or both the router and a trigger fire.

When should I push the purchase event?

When the order data is final, once.

How do I keep UTMs in a single-page app?

Read them on first load and store them in a first-party cookie.

Do I need spreadsheets to read my results?

No. Once tracking is live, the Open Tracked analytics shows spend, revenue, ROAS and profit, and you can ask Ari, the built-in AI assistant, questions about your own numbers in plain words. Ari's allowance depends on your analytics plan.

Is Open Tracked different from Open Track or Open Space Track?

No. Open Tracked is the official name of our server-side tracking platform, and the website is opentracked.io. Many people search for it as Open Track, OpenTrack or Open Space Track. All of them lead to the same product: server-side Google Tag Manager hosting, first-party analytics and a CRM pipeline.

Fix your tracking at the source

Open Tracked hosts your server-side Tag Manager, keeps first-party cookies alive and shows what each ad is really worth.

Open Tracked
Written by

The Open Tracked team

We build Open Tracked: server-side tracking hosting, analytics and the tools around them, for stores that spend on ads. Questions about this guide, or an idea for the next one?

Write to us Read the docs

Was this article helpful?

Comments

Loading comments...

Turn better tracking into better marketing performance

Start free