Next.js
Integration for Next.js 13+ with App Router or Pages Router.
Difficulty: Medium
Takes about 5-10 minutes
App Router (Next.js 13+)
Add the script to your root layout:
app/layout.tsx
import Script from 'next/script'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="sv">
<head>
<Script
defer
data-site-id="DIN-SAJT-ID"
data-api="https://besokskollen.se"
src="https://besokskollen.se/script.js"
strategy="afterInteractive"
/>
</head>
<body>{children}</body>
</html>
)
}Pages Router
Add the script to _app.tsx or _document.tsx:
pages/_app.tsx
import Script from 'next/script'
import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Script
defer
data-site-id="DIN-SAJT-ID"
data-api="https://besokskollen.se"
src="https://besokskollen.se/script.js"
strategy="afterInteractive"
/>
<Component {...pageProps} />
</>
)
}SPA Navigation
Our script automatically handles client-side navigation in Next.js. It hooks into history.pushState and popstate events to track page views when users navigate without a full page reload.
Custom events
To track events in React components:
'use client'
declare global {
interface Window {
va?: (type: string, name: string, props?: object) => void;
}
}
export function SignupButton() {
const handleClick = () => {
// Spåra eventet
window.va?.('event', 'Signup Click', { plan: 'pro' });
};
return (
<button onClick={handleClick}>
Registrera dig
</button>
);
}TypeScript tip
Add declare global to get TypeScript support for the window.va function.
Production only
If you only want to track in production:
{process.env.NODE_ENV === 'production' && (
<Script
defer
data-site-id="DIN-SAJT-ID"
data-api="https://besokskollen.se"
src="https://besokskollen.se/script.js"
strategy="afterInteractive"
/>
)}Content Security Policy (CSP)
If your site uses CSP, you need to allow besokskollen.se in your headers.
Next.js on Vercel?
Use vercel.json instead of next.config.js for CSP headers. This ensures headers are always sent correctly.
Need help?
See all integration guides → →