> ## 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.

# NextJS

> Add DATALYR tracking to your Next.js app with the Web SDK

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

* [ ] You have a DATALYR account
* [ ] You've created a workspace
* [ ] You have a Next.js project (App Router or Pages Router)
* [ ] Node.js 14+ installed

## 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

```bash theme={null}
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`**

```typescript theme={null}
'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`**

```typescript theme={null}
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`**:

```typescript theme={null}
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`**

```bash theme={null}
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`**:

```typescript theme={null}
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`**:

```typescript theme={null}
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

```typescript theme={null}
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)

```typescript theme={null}
'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:

```typescript theme={null}
import datalyr from '@datalyr/web'

// After user signs up or logs in
datalyr.identify('user_12345', {
  email: 'user@example.com',
  name: 'John Doe',
  plan: 'pro'
})
```

## Track Page Views (App Router)

For App Router, manually track page views on route changes:

```typescript theme={null}
'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:

```typescript theme={null}
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):

```typescript theme={null}
// 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:

```typescript theme={null}
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: 'user@example.com',
  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:

```bash theme={null}
npm install --save-dev @types/node
```

**SDK not found?**

If using script tag method, check that the script loads:

```typescript theme={null}
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

<CardGroup cols={2}>
  <Card title="Track Custom Events" icon="code" href="/sdks/web/custom-events">
    Learn the full event tracking API
  </Card>

  <Card title="Identify Users" icon="user" href="/sdks/web/identify">
    Track users across devices
  </Card>

  <Card title="Connect Integrations" icon="plug" href="/integrations/overview">
    Link Meta, Google, TikTok Ads
  </Card>

  <Card title="View Dashboard" icon="chart-line" href="/features/dashboard">
    See your tracking data
  </Card>
</CardGroup>

## Need Help?

Having issues with Next.js tracking? Check our [troubleshooting guide](/troubleshooting/tracking-not-working) or contact support.
