Skip to main content

Next.js

Installation

npm install @haya/analytics

App Router (Next.js 13+)

Create a client component that initializes Haya once:

// components/HayaProvider.tsx
'use client';

import { useEffect } from 'react';
import haya from '@haya/analytics';

export function HayaProvider() {
useEffect(() => {
haya.init(process.env.NEXT_PUBLIC_HAYA_SDK_KEY!, {
sessionReplay: true,
heatmaps: true,
autoTrack: { clicks: true, scrolls: true, pageviews: true },
maskInputs: true,
});

return () => {
haya.reset();
};
}, []);

return null;
}

Add it to your root layout:

// app/layout.tsx
import { HayaProvider } from '@/components/HayaProvider';

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<HayaProvider />
{children}
</body>
</html>
);
}

Add the environment variable:

# .env.local
NEXT_PUBLIC_HAYA_SDK_KEY=your_sdk_key_here

Pages Router (Next.js 12 and earlier)

Initialize in _app.tsx:

// pages/_app.tsx
import type { AppProps } from 'next/app';
import { useEffect } from 'react';
import haya from '@haya/analytics';

export default function App({ Component, pageProps }: AppProps) {
useEffect(() => {
haya.init(process.env.NEXT_PUBLIC_HAYA_SDK_KEY!, {
sessionReplay: true,
heatmaps: true,
autoTrack: { clicks: true, scrolls: true, pageviews: true },
maskInputs: true,
});
}, []);

return <Component {...pageProps} />;
}

Tracking route changes

Next.js App Router — Haya's pushState patching handles this automatically.

Next.js Pages Router — listen to the routeChangeComplete event for explicit pageview tracking:

// pages/_app.tsx
import Router from 'next/router';
import haya from '@haya/analytics';

Router.events.on('routeChangeComplete', (url) => {
haya.track('pageview', { url });
});

Tracking custom events in Server Components

haya.track() is a browser-only call. In Server Components, pass tracking down as a client-side callback:

// app/pricing/page.tsx (Server Component)
import { UpgradeButton } from './UpgradeButton';

export default function PricingPage() {
return <UpgradeButton plan="pro" />;
}
// app/pricing/UpgradeButton.tsx
'use client';
import haya from '@haya/analytics';

export function UpgradeButton({ plan }: { plan: string }) {
return (
<button onClick={() => haya.track('upgrade_clicked', { plan })}>
Upgrade to {plan}
</button>
);
}

:::info NEXT_PUBLIC_ prefix Next.js only exposes environment variables prefixed with NEXT_PUBLIC_ to the browser. Your SDK key is a public identifier so this is intentional and safe. See Security. :::