Angular
This guide covers installing the DAP SDK in Angular applications, including SSR with Angular Universal.
Prerequisites
- Angular 14+
Option A — index.html (Recommended)
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");
}
}
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
-
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
- Open your application in a browser.
- Open the developer console (
F12orCmd+Option+I). - Type
window.DAPand press Enter. You should see the DAP function object. - Enable debug mode for detailed logs:
DAP("init", { tenantKey: "YOUR_TENANT_KEY", debug: true });
- Check the Console tab for messages prefixed with
[DAP]confirming successful initialization.
Next Steps
- SDK Configuration -- customize SDK behavior
- User Identity -- identify users for targeted content
- SDK Events -- listen to SDK lifecycle events