Skip to main content

Angular

This guide covers installing the DAP SDK in Angular applications, including SSR with Angular Universal.

Prerequisites

  • Angular 14+

Add the snippet to src/index.html inside the <head> tag:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- DAP SDK Snippet -->
<script>
(function (w, d, s, o, f, js, fjs) {
w["DAPObject"] = f;
w[f] =
w[f] ||
function () {
(w[f].q = w[f].q || []).push(arguments);
};
w[f].l = 1 * new Date();
js = d.createElement(s);
fjs = d.getElementsByTagName(s)[0];
js.id = f;
js.src = o;
js.async = 1;
js.crossOrigin = "anonymous";
fjs.parentNode.insertBefore(js, fjs);
})(window, document, "script", "https://cdn.example.com/sdk.js", "DAP");
DAP("init", { tenantKey: "YOUR_TENANT_KEY" });
</script>
</head>
<body>
<app-root></app-root>
</body>
</html>

This is the simplest approach and works for all Angular versions.

Option B — Angular Service

For programmatic control over SDK loading, create a dedicated service:

import { Injectable, Inject } from "@angular/core";
import { DOCUMENT } from "@angular/common";

@Injectable({ providedIn: "root" })
export class SdkService {
private initialized = false;

constructor(@Inject(DOCUMENT) private document: Document) {}

init(tenantKey: string): void {
if (this.initialized) return;
this.initialized = true;

const win = this.document.defaultView as Window & typeof globalThis;
if (!win) return;

win["DAPObject"] = "DAP";
const q: unknown[][] = [];
win["DAP"] = Object.assign(
(...args: unknown[]) => {
q.push(args);
},
{ q, l: Date.now() },
);

const script = this.document.createElement("script");
script.id = "breakground-dap";
script.src = "https://cdn.example.com/sdk.js";
script.async = true;
script.crossOrigin = "anonymous";
this.document.head.appendChild(script);

win["DAP"]("init", { tenantKey });
}
}

Call the service from your root component:

import { Component, OnInit } from "@angular/core";
import { SdkService } from "./sdk.service";

@Component({
selector: "app-root",
templateUrl: "./app.component.html",
})
export class AppComponent implements OnInit {
constructor(private sdk: SdkService) {}

ngOnInit(): void {
this.sdk.init("YOUR_TENANT_KEY");
}
}
tip

Using @Inject(DOCUMENT) instead of accessing document directly makes the service safe for Angular Universal (SSR), where document is not available on the server.

TypeScript Support

Add a type declaration file at src/typings.d.ts or src/breakground.d.ts:

declare global {
interface Window {
DAP: ((...args: unknown[]) => void) & { q?: unknown[][]; l?: number };
DAPObject: string;
}
}

export {};

Ensure the file is included in tsconfig.app.json:

{
"include": ["src/**/*.d.ts"]
}

SPA Route Changes

The SDK auto-detects URL changes by monitoring pushState and popstate events. Standard Angular Router navigation is handled automatically.

For cases where you need to manually trigger a content refresh (for example, after a route parameter change that does not alter the URL path), subscribe to Router events:

import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';

constructor(private router: Router) {
this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe(() => {
(window as any).DAP('refreshContent');
});
}

Angular Universal (SSR)

When using server-side rendering, the SDK must only run in the browser. Guard all DAP calls with a platform check:

import { Component, OnInit, Inject, PLATFORM_ID } from "@angular/core";
import { isPlatformBrowser } from "@angular/common";

@Component({
selector: "app-root",
templateUrl: "./app.component.html",
})
export class AppComponent implements OnInit {
constructor(@Inject(PLATFORM_ID) private platformId: object) {}

ngOnInit(): void {
if (isPlatformBrowser(this.platformId)) {
DAP("init", { tenantKey: "YOUR_TENANT_KEY" });
}
}
}

Gotchas

warning
  • SDK runs outside Angular zone: The SDK operates outside Angular's change detection. If you use SDK callbacks that update component state, wrap them in NgZone.run():

    constructor(private ngZone: NgZone) {}

    ngOnInit(): void {
    DAP('on', 'ready', () => {
    this.ngZone.run(() => {
    this.sdkReady = true;
    });
    });
    }
  • Standalone components (Angular 17+): Work identically to NgModule-based components. No special configuration is needed.

Verification

  1. Open your application in a browser.
  2. Open the developer console (F12 or Cmd+Option+I).
  3. Type window.DAP and press Enter. You should see the DAP function object.
  4. Enable debug mode for detailed logs:
DAP("init", { tenantKey: "YOUR_TENANT_KEY", debug: true });
  1. Check the Console tab for messages prefixed with [DAP] confirming successful initialization.

Next Steps