Next.js
Install EngageTrack in your Next.js application using the App Router.
Next.js
Add EngageTrack analytics to your Next.js application in a few minutes. This guide covers the App Router (Next.js 13+). The SDK handles client-side navigation automatically — no extra configuration needed.
1. Add the Script to Your Root Layout
Open app/layout.tsx and add the EngageTrack script using the Next.js Script component:
import Script from "next/script";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Script
defer
data-site-id={process.env.NEXT_PUBLIC_ENGAGETRACK_SITE_ID}
src="https://cdn.engagetrack.net/sdk.js"
strategy="afterInteractive"
/>
</body>
</html>
);
}Using strategy="afterInteractive" ensures the script loads after the page
becomes interactive, keeping your Core Web Vitals scores high.
2. Set Your Environment Variable
Add your Site ID to .env.local:
NEXT_PUBLIC_ENGAGETRACK_SITE_ID=your-site-id-hereThe variable must be prefixed with NEXT_PUBLIC_ so Next.js exposes it to the
browser. Never put secret keys in NEXT_PUBLIC_ variables.
3. SPA Pageview Tracking
The EngageTrack SDK automatically detects client-side navigations by listening to the History API (pushState / replaceState). No additional setup is required for the App Router or next/link transitions — every route change is tracked as a pageview.
If your app uses hash-based routing, add the data-hash attribute:
<Script
defer
data-site-id={process.env.NEXT_PUBLIC_ENGAGETRACK_SITE_ID}
data-hash="true"
src="https://cdn.engagetrack.net/sdk.js"
strategy="afterInteractive"
/>4. Track Goals from Components
Use the window.engagetrack API inside event handlers or effects:
"use client";
export function SignupButton() {
const handleClick = () => {
window.engagetrack("signup-click", { plan: "pro" });
};
return <button onClick={handleClick}>Sign Up</button>;
}TypeScript users: create a engagetrack.d.ts file in your project root to
avoid type errors:
declare function engagetrack(
event: string,
props?: Record<string, string | number | boolean>
): void;
declare namespace engagetrack {
function track(
event: string,
props?: Record<string, string | number | boolean>
): void;
function identify(
userId: string,
traits?: {
name?: string;
email?: string;
avatar?: string;
custom?: Record<string, string | number | boolean>;
}
): void;
function trackPurchase(
orderId: string,
revenue: number,
currency?: string
): void;
function getVisitorId(): string;
function getSessionId(): string;
function ignore(): void;
function unignore(): void;
}
interface Window {
engagetrack: typeof engagetrack;
}5. Server-Side Revenue Attribution
EngageTrack stores visitor and session IDs in cookies (engagetrack_visitor_id, engagetrack_session_id). You can read these in API routes or Server Actions to attribute server-side conversions:
// app/api/checkout/route.ts
import { cookies } from "next/headers";
export async function POST(request: Request) {
const cookieStore = await cookies();
const visitorId = cookieStore.get("engagetrack_visitor_id")?.value;
const sessionId = cookieStore.get("engagetrack_session_id")?.value;
// Send a server-side event to EngageTrack
await fetch("https://api.engagetrack.net/api/v1/event", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
site_id: process.env.NEXT_PUBLIC_ENGAGETRACK_SITE_ID,
name: "purchase",
visitor_id: visitorId,
session_id: sessionId,
revenue: 49.99,
currency: "USD",
url: request.headers.get("referer") || "",
}),
});
return Response.json({ success: true });
}Server-side events require the visitor/session ID from cookies. If the user has cleared cookies or is in a new session, attribution will not be possible. For reliable revenue tracking, consider using a payment provider integration instead.
Verify Installation
- Deploy your changes (or run
pnpm devlocally). - Open your site in a browser and navigate between a few pages.
- In the EngageTrack dashboard, go to the Realtime tab — you should see your visits appearing within seconds.
If you see your pageviews in Realtime, you're all set. If not, open the
browser console and add data-debug="true" to the script tag to enable debug
logging.