Skip to main content

Next.js

This guide covers installing the DAP SDK in Next.js applications using the App Router (Next.js 13+) or Pages Router (Next.js 12+).

Prerequisites

  • Next.js 13+ (App Router) or Next.js 12+ (Pages Router)

App Router

Add the SDK to your root layout using the next/script component. Place two Script tags in app/layout.tsx: one for the SDK bundle and one for initialization.

import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script
id="breakground-dap-sdk"
src="https://cdn.example.com/sdk.js"
strategy="afterInteractive"
crossOrigin="anonymous"
/>
<Script id="breakground-dap-init" strategy="afterInteractive">
{`
window.DAPObject = 'DAP';
window.DAP = window.DAP || function() {
(window.DAP.q = window.DAP.q || []).push(arguments);
};
window.DAP.l = Date.now();
DAP('init', { tenantKey: 'YOUR_TENANT_KEY' });
`}
</Script>
</body>
</html>
);
}

Using a Client Component

Alternatively, create a 'use client' component with the dynamic injection pattern:

"use client";

import { useEffect } from "react";

let sdkBootstrapped = false;

export function BreakGroundSDK() {
useEffect(() => {
if (sdkBootstrapped) return;
sdkBootstrapped = true;

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

let script = document.getElementById(
"breakground-dap",
) as HTMLScriptElement | null;
if (!script) {
script = document.createElement("script");
script.id = "breakground-dap";
script.src = "https://cdn.example.com/sdk.js";
script.async = true;
script.crossOrigin = "anonymous";
document.head.appendChild(script);
}

window.DAP("init", { tenantKey: "YOUR_TENANT_KEY" });
}, []);

return null;
}

Then include <BreakGroundSDK /> in your root layout.

Pages Router

Add the snippet to pages/_document.tsx inside the <Head> component:

import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
return (
<Html>
<Head>
<script
dangerouslySetInnerHTML={{
__html: `
(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' });
`,
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}

Using _app.tsx

Alternatively, initialize in pages/_app.tsx with useEffect:

import { useEffect } from 'react';
import type { AppProps } from 'next/app';

let sdkBootstrapped = false;

export default function App({ Component, pageProps }: AppProps) {
useEffect(() => {
if (sdkBootstrapped) return;
sdkBootstrapped = true;

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

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

window.DAP('init', { tenantKey: 'YOUR_TENANT_KEY' });
}, []);

return <Component {...pageProps} />;
}

TypeScript Support

Create a breakground.d.ts file in your project root:

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

export {};

Ensure the file is included in your tsconfig.json:

{
"include": ["breakground.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx"]
}
warning

Do not modify next-env.d.ts. Next.js regenerates this file automatically. Add your declarations in a separate file.

SPA Route Changes

Client-side navigation in Next.js (both App Router and Pages Router) is handled automatically by the SDK's pushState and popstate monitoring. No additional configuration is needed.

Gotchas

warning
  • Client-side only: All DAP code must run in the browser. Use useEffect or mark components with 'use client'. Server Components and server-side code cannot access window.
  • Script strategy: Use strategy="afterInteractive" with next/script. Do not use "beforeInteractive" as it can delay page hydration.
  • Middleware and Edge Functions: The SDK is a client-side library and cannot be used in Next.js middleware or edge functions.
  • Environment variables: Use the NEXT_PUBLIC_ prefix for any values referenced in client-side code (e.g., NEXT_PUBLIC_TENANT_KEY).

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