Next.js Integration
Better Analytics provides seamless integration with Next.js applications with automatic initialization for both client and server-side tracking.
Installation
pnpm add better-analyticsSetup
Add the Analytics component to your layout - this automatically enables both client and server-side tracking:
import { Analytics } from 'better-analytics/next'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<Analytics site="your-site-id" />
{children}
</body>
</html>
)
}Environment Variables
Set up your environment variables once and they work for both client and server:
# Required: Your site identifier
NEXT_PUBLIC_BA_SITE=your-site-id
# Optional: Custom endpoint (defaults to Better Analytics SaaS)
NEXT_PUBLIC_BA_URL=https://your-endpoint.com/api/collect
# Optional: Server-only variables
BA_API_KEY=your-server-api-key # For server-side authentication
BA_DEBUG=true # Enable server-side debug loggingHow it works:
NEXT_PUBLIC_BA_SITE- Used by both client and serverNEXT_PUBLIC_BA_URL- Used by both client and serverBA_API_KEY- Server-only (for authentication)BA_DEBUG- Server-only (debug logging)
Component Configuration
<Analytics
site="your-site-id" // Required if not in env
api="/api/collect" // Custom endpoint
mode="auto" // auto | development | production
debug={false} // Enable console logging
beforeSend={(event) => event} // Transform events
/>Automatic Features
Page Tracking
The Analytics component automatically tracks:
- Route changes - Both App Router and Pages Router
- Dynamic routes - Converts
/user/123to/user/[id] - Search parameters - Included in page context
- Page metadata - Title, pathname, and load time
Route Computation
Next.js dynamic routes are automatically computed:
// /user/123/settings → /user/[id]/settings
// /blog/[...slug] → /blog/[...slug]
// /shop/[category]/[product] → /shop/[category]/[product]Client-side Tracking
Manual Events
Track custom events in client components:
'use client'
import { track, identify } from 'better-analytics/next'
export default function MyComponent() {
const handleClick = () => {
track('button_click', {
button: 'signup',
location: 'header'
})
}
const handleLogin = (userId: string) => {
identify(userId, {
email: 'user@example.com',
plan: 'pro'
})
}
return (
<button onClick={handleClick}>
Sign Up
</button>
)
}React Hooks
Use analytics in React components:
'use client'
import { useEffect } from 'react'
import { track } from 'better-analytics/next'
export default function ProductPage({ product }) {
useEffect(() => {
track('product_viewed', {
product_id: product.id,
category: product.category,
price: product.price
})
}, [product])
return <div>{product.name}</div>
}Server-side Tracking
Auto-initialization
Server functions automatically initialize using your environment variables - no manual setup needed:
// No initialization needed - automatically uses NEXT_PUBLIC_BA_SITE and other env vars
import { trackServer } from 'better-analytics/next'
await trackServer('purchase', {
value: 99.99,
currency: 'USD'
})API Routes
// app/api/purchase/route.ts
import { trackServer } from 'better-analytics/next'
export async function POST(request: Request) {
const body = await request.json()
// Your purchase logic here
await trackServer('purchase', {
value: body.amount,
currency: body.currency,
payment_method: body.paymentMethod
}, {
headers: request.headers
})
return Response.json({ success: true })
}Server Actions
// app/actions.ts
'use server'
import { trackServer } from 'better-analytics/next'
export async function createUser(formData: FormData) {
// Your user creation logic
await trackServer('user_created', {
method: 'form',
source: 'signup_page'
})
}Server Components
Track events in Server Components:
// app/page.tsx
import { trackPageviewServer } from 'better-analytics/next'
import { headers } from 'next/headers'
export default async function HomePage() {
// Track server-side page view
await trackPageviewServer('/', {
headers: headers()
})
return <div>Welcome!</div>
}Middleware
Track requests in Next.js middleware:
// middleware.ts
import { NextResponse } from 'next/server'
import { trackServer } from 'better-analytics/next'
export async function middleware(request) {
await trackServer('middleware_request', {
pathname: request.nextUrl.pathname,
method: request.method
}, {
headers: request.headers
})
return NextResponse.next()
}Session Stitching
Connect client and server events for the same user:
// app/api/purchase/route.ts
import { trackServer, stitchSession } from 'better-analytics/next'
export async function POST(request: Request) {
// Get client session from cookies
const clientSessionId = request.cookies.get('ba_session')?.value
const clientDeviceId = request.cookies.get('ba_device')?.value
await trackServer('purchase', {
value: 99.99,
currency: 'USD'
}, {
headers: request.headers,
user: stitchSession(clientSessionId, clientDeviceId)
})
return Response.json({ success: true })
}TypeScript Support
Full TypeScript support with Next.js-specific types:
import type { AnalyticsProps, ServerTrackOptions } from 'better-analytics/next'
// Component props
const analyticsProps: AnalyticsProps = {
site: 'your-site-id',
debug: true,
beforeSend: (event) => {
// Type-safe event transformation
return event
}
}
// Server options
const serverOptions: ServerTrackOptions = {
headers: request.headers,
user: { id: 'user-123' }
}Development Workflow
# Enable debug logging
BA_DEBUG=true pnpm dev
# Or in your scripts
{
"scripts": {
"dev": "BA_DEBUG=true next dev",
"dev:analytics": "BA_DEBUG=true NEXT_PUBLIC_BA_DEBUG=true next dev"
}
}Best Practices
- Use Analytics component in layout - Single setup works for everything
- Use NEXT_PUBLIC_ variables - Work for both client and server
- Track server-side conversions - More reliable than client-side
- Use session stitching - Connect client and server events
- Enable debug in development - Monitor events during development
Troubleshooting
Events Not Appearing
- Check that
NEXT_PUBLIC_BA_SITEis set - Verify the Analytics component is in your layout
- Enable debug mode to see console logs
- Check network tab for outgoing requests
Server Events Not Working
- Ensure
NEXT_PUBLIC_BA_SITEis set (used by server as fallback) - Enable
BA_DEBUG=truefor server logging - Check server logs for errors
- Verify server functions are being called
Route Tracking Issues
- Ensure Analytics component is in the layout
- Check dynamic route parameters
- Verify route computation with debug mode
- Test with both App Router and Pages Router
How is this guide?