Next.js Quickstart
Integrate Zenovay Analytics into your Next.js application. Supports both App Router (Next.js 13+) and Pages Router.
Installation
No npm package is needed. Zenovay uses a lightweight tracking script that you add to your layout.
Setup with App Router (Next.js 13+)
Add Tracking Script
Add the Zenovay tracking script to your root layout using Next.js's Script component:
import Script from 'next/script';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Script
defer
data-tracking-code="YOUR_TRACKING_CODE"
src="https://api.zenovay.com/z.js"
strategy="afterInteractive"
/>
</body>
</html>
);
}That's it! Zenovay will now automatically track page views in your Next.js app.
Setup with Pages Router
Add Script to Custom App
Update your _app.tsx file:
import Script from 'next/script';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<Script
defer
data-tracking-code="YOUR_TRACKING_CODE"
src="https://api.zenovay.com/z.js"
strategy="afterInteractive"
/>
</>
);
}Track Custom Events
Use window.zenovay to track custom events in your components:
'use client';
export function SignupButton() {
const handleSignup = async () => {
// Your signup logic here
const user = await signup();
// Track the event
if (window.zenovay) {
window.zenovay('track', 'user_signup', {
plan: 'free',
source: 'homepage',
});
}
};
return (
<button onClick={handleSignup}>
Sign Up
</button>
);
}Server-Side Tracking
For server-side event tracking, send events directly to the Zenovay tracking endpoint. This is a public endpoint that does not require an API key:
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { amount } = await request.json();
// Process payment...
// Track conversion server-side via the public tracking endpoint
await fetch('https://api.zenovay.com/e/YOUR_TRACKING_CODE', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'User-Agent': request.headers.get('user-agent') || '',
'X-Forwarded-For': request.headers.get('x-forwarded-for') || '',
},
body: JSON.stringify({
type: 'event',
payload: {
name: 'purchase_complete',
url: 'https://yoursite.com/checkout',
props: { amount, currency: 'USD' },
},
}),
});
return NextResponse.json({ success: true });
}The tracking endpoint (/e/:trackingCode) is public and does not require an API key. Forward the original user's User-Agent and IP address for accurate visitor attribution.
Identify Users
Associate events with authenticated users:
'use client';
import { useEffect } from 'react';
import { useUser } from '@/hooks/useUser';
export default function Dashboard() {
const { user } = useUser();
useEffect(() => {
if (user && window.zenovay) {
window.zenovay('identify',user.id, {
email: user.email,
name: user.name,
plan: user.subscription?.plan,
});
}
}, [user]);
return <div>Dashboard</div>;
}Track Link Clicks
Track external link clicks:
'use client';
export function ExternalLink({ href, children }: { href: string; children: React.ReactNode }) {
const handleClick = () => {
if (window.zenovay) {
window.zenovay('track', 'external_link_click', {
url: href,
text: children?.toString(),
});
}
};
return (
<a
href={href}
onClick={handleClick}
target="_blank"
rel="noopener noreferrer"
>
{children}
</a>
);
}SPA Page View Tracking
For client-side navigation tracking in the App Router:
'use client';
import { usePathname, useSearchParams } from 'next/navigation';
import { useEffect } from 'react';
export function Analytics() {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (window.zenovay) {
window.zenovay('track', 'pageview', {
path: pathname,
title: document.title,
});
}
}, [pathname, searchParams]);
return null;
}
// Add to your root layout:
// <Analytics />TypeScript Support
Add type declarations for the global zenovay object:
declare global {
interface Window {
zenovay: (...args: any[]) => void;
}
}
export {};Testing in Development
In development, you can check that events are being sent by opening the browser console and watching for network requests to api.zenovay.com. The Zenovay dashboard also shows real-time event data.
// Optional: Create a helper hook for cleaner tracking calls
export function useZenovay() {
const track = (eventName: string, data?: Record<string, any>) => {
if (window.zenovay) {
window.zenovay('track',eventName, data);
}
};
const identify = (userId: string, traits?: Record<string, any>) => {
if (window.zenovay) {
window.zenovay('identify', userId, traits);
}
};
const trackGoal = (goalName: string, data?: Record<string, any>) => {
if (window.zenovay) {
window.zenovay('goal', goalName, data);
}
};
return { track, identify, trackGoal };
}Next Steps
Your Next.js app is now tracking analytics with Zenovay! Check your dashboard to see real-time data.
Continue learning:
- Custom Events - Track specific user actions
- Privacy Compliance - GDPR and CCPA setup
- Dashboard Overview - Understand your data