Skip to main content

Single-Page App SDK

Tracking Single Page Applications necessitates technical expertise and direct access to the codebase. It cannot be implemented through Google Tag Manager (GTM) or any analogous platforms.

For SPAs you can install Dreamdata Analytics directly through our NPM package:

# npm
npm install @dreamdata/analytics-next

# yarn
yarn add @dreamdata/analytics-next

# pnpm
pnpm add @dreamdata/analytics-next

After installing the package you initialize it as done below:

import { AnalyticsBrowser } from "@dreamdata/analytics-next";

export const dreamdata = AnalyticsBrowser.load({
writeKey: "<YOUR_WRITE_KEY>",
});

You get the write key YOUR_WRITE_KEY by navigating to the app.dreamdata.io/<SLUG>/data-platform/sources/dreamdata page in the app.

Page Tracking​

In SPAs, navigating between views does not involve loading new HTML pages. Instead, views are rendered dynamically based on route changes, typically handled by routing libraries.

React Example​

If you're using React Router, you can make use of the useLocation and useEffect hooks to get the equivalent of page tracking as done below. Note that this needs to be in a top-level component.

import { useLocation } from "react-router-dom";
import { useEffect } from "react";

const App = () => {
const location = useLocation();
useEffect(() => {
dreamdata.page();
}, [location.pathname]);

// Rest of app...
};

This snippet ensures that dreamdata.page() is called every time the URL's pathname changes, capturing each navigation event.

Next Example​

See this example from Vercel. You can substitute the dependency @segment/analytics-next for @dreamdata/analytics-next.

Angular Example​

In Angular, route changes are tracked similarly by subscribing to router events:

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

@Component({
// Component metadata...
})
export class AppComponent implements OnInit {
constructor(private router: Router) {}

ngOnInit() {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
dreamdata.page();
}
});
}
}

Vue Example​

In Vue when using Vue router, you can listen to and track router events like below:

import { createRouter, createWebHistory } from "vue-router";

const router = createRouter({
history: createWebHistory(),
// Your props
routes: [
// Your routes...
],
});

router.afterEach(() => {
dreamdata.page();
});

Nuxt example​

The easiest way to to integrate Nuxt with Analytics is by creating a client side plugin. To do this, create a plugin plugins/dreamdata.client.ts containing the following

import { AnalyticsBrowser } from "@dreamdata/analytics-next";

export default defineNuxtPlugin((nuxtApp) => {
const dreamdata = AnalyticsBrowser.load({
writeKey: "<YOUR_WRITE_KEY>",
});

// Track page events. Note that this does not track e.g. 404s
nuxtApp.hook("page:finish", () => {
dreamdata.page();
});

return {
provide: {
dreamdata,
},
};
});

You can access your analytics instance to e.g. track custom events through const { $dreamdata } = useNuxtApp();.

Tracking Forms​

Tracking forms in SPAs often involves attaching handlers to form submission events.

Take a look at Manual Tracking for more information.

Cookieless​

Our recommended approach is to use our NPM package and creating two Analytics instances, as done below:

import { AnalyticsBrowser } from "@dreamdata/analytics-next";

export const dreamdata = AnalyticsBrowser.load({
writeKey: "<YOUR_WRITE_KEY>",
});
export const dreamdataCookieless = AnalyticsBrowser.load(
{
writeKey: "<YOUR_WRITE_KEY>",
},
{ anonymous: true },
);

Then tracking can be done as

if (user.hasConsented) {
dreamdata.track("Clicked button");
} else {
dreamdataCookieless.track("Clicked button");
}

Note that identify calls are not allowed on an instance loaded with anonymous: true.

Custom Options​

It is possible to pass custom options as a second argument when initiating AnalyticsBrowser as done below:

export const dreamdata = AnalyticsBrowser.load(
{ writeKey: "<YOUR_WRITE_KEY>" },
{
anonymizeIPs: false,
googleEnhancedConversions: false,
intentSources: { autoGroup: true },
},
);

The available options are:

  • anonymizeIPs (default false) to anonymize IP addresses. Note: Turning this on might affect the data shown in your reports. See this page for more information.
  • googleEnhancedConversions (default false) to enable support for Google Enhanced Conversions For Web.
  • intentSources (not specified by default) to enable Hybrid Intent. See snippet above on how it should be specified.