Documentation Index Fetch the complete documentation index at: https://docs.datalyr.com/llms.txt
Use this file to discover all available pages before exploring further.
Add DATALYR to your Next.js app (App Router or Pages Router) using the @datalyr/web SDK for TypeScript support and advanced tracking.
Use Cases
SaaS Applications
Track signups, feature usage, and subscription conversions with full TypeScript support.
E-commerce
Track product views, cart interactions, and purchases with server-side rendering support.
Marketing Sites
Monitor landing page performance, form submissions, and ad campaign attribution.
Web Apps
Track user behavior, feature adoption, and custom events with full control.
Before You Start
Installation Method
Choose between SDK (recommended) or Script tag:
Method 1: Using @datalyr/web SDK (Recommended)
Full TypeScript support, type-safe events, and programmatic control.
Method 2: Using Script Tag
Simple HTML script in your layout file. No npm install needed.
Method 1: Install @datalyr/web SDK
Step 1: Install the Package
npm install @datalyr/web
# or
yarn add @datalyr/web
# or
pnpm add @datalyr/web
Step 2: Initialize in App Router (Next.js 13+)
Create a client component for DATALYR initialization:
app/providers/datalyr-provider.tsx
'use client'
import { useEffect } from 'react'
import { datalyr } from '@datalyr/web'
export function DatalyrProvider ({ children } : { children : React . ReactNode }) {
useEffect (() => {
// Initialize DATALYR
datalyr . init ({
workspaceId: process . env . NEXT_PUBLIC_DATALYR_WORKSPACE_ID ! ,
debug: process . env . NODE_ENV === 'development' ,
trackSessions: true ,
})
// Track initial page view
datalyr . page ()
}, [])
return <>{ children } </>
}
Add to your root layout:
app/layout.tsx
import { DatalyrProvider } from './providers/datalyr-provider'
export default function RootLayout ({ children } : { children : React . ReactNode }) {
return (
< html lang = "en" >
< body >
< DatalyrProvider >
{ children }
</ DatalyrProvider >
</ body >
</ html >
)
}
Step 3: Initialize in Pages Router (Next.js 12 and below)
Add to pages/_app.tsx :
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { datalyr } from '@datalyr/web'
import type { AppProps } from 'next/app'
function MyApp ({ Component , pageProps } : AppProps ) {
const router = useRouter ()
useEffect (() => {
// Initialize DATALYR
datalyr . init ({
workspaceId: process . env . NEXT_PUBLIC_DATALYR_WORKSPACE_ID ! ,
debug: process . env . NODE_ENV === 'development' ,
trackSessions: true ,
})
// Track initial page view
datalyr . page ()
// Track route changes
const handleRouteChange = ( url : string ) => {
datalyr . page ({ path: url })
}
router . events . on ( 'routeChangeComplete' , handleRouteChange )
return () => router . events . off ( 'routeChangeComplete' , handleRouteChange )
}, [ router . events ])
return < Component { ... pageProps } />
}
export default MyApp
Step 4: Add Environment Variable
.env.local
NEXT_PUBLIC_DATALYR_WORKSPACE_ID = your_workspace_id_here
Get your workspace ID from DATALYR Dashboard → Settings → Tracking .
Method 2: Using Script Tag
App Router (Next.js 13+)
Add to app/layout.tsx :
import Script from 'next/script'
export default function RootLayout ({ children } : { children : React . ReactNode }) {
return (
< html lang = "en" >
< head >
< Script
src = "https://track.datalyr.com/dl.js"
data - workspace - id = {process.env. NEXT_PUBLIC_DATALYR_WORKSPACE_ID }
strategy = "afterInteractive"
/>
</ head >
< body >{ children } </ body >
</ html >
)
}
Pages Router
Add to pages/_document.tsx :
import { Html , Head , Main , NextScript } from 'next/document'
import Script from 'next/script'
export default function Document () {
return (
< Html >
< Head >
< Script
src = "https://track.datalyr.com/dl.js"
data - workspace - id = {process.env. NEXT_PUBLIC_DATALYR_WORKSPACE_ID }
strategy = "afterInteractive"
/>
</ Head >
< body >
< Main />
< NextScript />
</ body >
</ Html >
)
}
Track Custom Events
Using @datalyr/web SDK
import { datalyr } from '@datalyr/web'
// Track button click
function handleClick () {
datalyr . track ( 'button_clicked' , {
button_name: 'Sign Up' ,
location: 'hero_section'
})
}
// Track form submission
function handleFormSubmit ( email : string ) {
datalyr . track ( 'form_submission' , {
form_type: 'newsletter' ,
email: email
})
}
// Track purchase
function handlePurchase ( orderId : string , amount : number ) {
datalyr . track ( 'purchase' , {
order_id: orderId ,
revenue: amount ,
currency: 'USD'
})
}
Using window.datalyr (Script Tag Method)
'use client'
function handleClick () {
if ( window . datalyr ) {
window . datalyr . track ( 'button_clicked' , {
button_name: 'Sign Up' ,
location: 'hero_section'
})
}
}
Identify Users
Track users for cross-device attribution:
import { datalyr } from '@datalyr/web'
// After user signs up or logs in
datalyr . identify ( 'user_12345' , {
email: '[email protected] ' ,
name: 'John Doe' ,
plan: 'pro'
})
Track Page Views (App Router)
For App Router, manually track page views on route changes:
'use client'
import { usePathname , useSearchParams } from 'next/navigation'
import { useEffect } from 'react'
import { datalyr } from '@datalyr/web'
export function PageViewTracker () {
const pathname = usePathname ()
const searchParams = useSearchParams ()
useEffect (() => {
const url = pathname + ( searchParams ?. toString () ? `? ${ searchParams } ` : '' )
datalyr . page ({ path: url })
}, [ pathname , searchParams ])
return null
}
Add to your root layout:
import { PageViewTracker } from './page-view-tracker'
export default function RootLayout ({ children } : { children : React . ReactNode }) {
return (
< html >
< body >
< PageViewTracker />
{ children }
</ body >
</ html >
)
}
Server-Side Tracking
For server-side events (API routes, Server Components):
// app/api/purchase/route.ts
import { NextResponse } from 'next/server'
export async function POST ( request : Request ) {
const body = await request . json ()
// Send server-side event to DATALYR
await fetch ( 'https://ingest.datalyr.com/events' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
workspaceId: process . env . DATALYR_WORKSPACE_ID ,
events: [{
eventName: 'purchase' ,
timestamp: new Date (). toISOString (),
properties: {
order_id: body . orderId ,
revenue: body . amount ,
currency: 'USD' ,
}
}]
})
})
return NextResponse . json ({ success: true })
}
TypeScript Support
The @datalyr/web SDK includes full TypeScript definitions:
import { datalyr , type EventProperties , type UserTraits } from '@datalyr/web'
// Type-safe event tracking
const properties : EventProperties = {
button_name: 'Sign Up' ,
location: 'hero_section'
}
datalyr . track ( 'button_clicked' , properties )
// Type-safe user identification
const traits : UserTraits = {
email: '[email protected] ' ,
name: 'John Doe' ,
plan: 'pro'
}
datalyr . identify ( 'user_123' , traits )
Troubleshooting
Events not showing in dashboard?
Check that:
Your workspace ID is correct in environment variables
You’re using NEXT_PUBLIC_ prefix for client-side variables
SDK is initialized before tracking events
Ad blockers are disabled
Duplicate page views?
Make sure you’re only initializing DATALYR once (in _app.tsx or root layout, not in individual pages).
TypeScript errors?
Install type definitions:
npm install --save-dev @types/node
SDK not found?
If using script tag method, check that the script loads:
useEffect (() => {
console . log ( 'DATALYR loaded:' , !! window . datalyr )
}, [])
What Gets Tracked Automatically
The SDK automatically captures:
Page views (when you call datalyr.page())
Visitor IDs (persistent across sessions)
UTM parameters and ad click IDs
Referrer and traffic source
Device and browser information
Session tracking
Next Steps
Track Custom Events Learn the full event tracking API
Identify Users Track users across devices
Connect Integrations Link Meta, Google, TikTok Ads
View Dashboard See your tracking data
Need Help?
Having issues with Next.js tracking? Check our troubleshooting guide or contact support.