Next.js
Add Vendo tracking to your Next.js app. Both App Router and Pages Router are supported.
App Router
Add the CDN snippet to your root layout using Next.js’s <Script> component:
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<Script id="vendo-tracking" strategy="afterInteractive">
{`
(function(w,d,s,e,l,k){w['VendoObject']=e;w[e]=w[e]||function(){
(w[e].q=w[e].q||[]).push(arguments)};w[e].l=1*new Date();
l=d.createElement(s);k=d.getElementsByTagName(s)[0];
l.async=1;l.src='https://cdn.vendodata.com/sdk/v1/vendo.js';k.parentNode.insertBefore(l,k);
})(window,document,'script','vendo');
vendo('init', 'YOUR_WRITE_KEY', {
host: 'https://YOUR_TRACKING_ENDPOINT',
trackPageViews: true
});
`}
</Script>
</head>
<body>{children}</body>
</html>
);
}Track Client-Side Navigations
Next.js client-side navigations don’t trigger a full page load, so the SDK’s automatic page view won’t fire. Add a route-change listener component:
// components/track-page-views.tsx
'use client';
import { usePathname, useSearchParams } from 'next/navigation';
import { useEffect } from 'react';
declare global {
interface Window {
vendo?: (...args: unknown[]) => void;
}
}
export function TrackPageViews() {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (typeof window.vendo === 'function') {
window.vendo('page');
}
}, [pathname, searchParams]);
return null;
}Add <TrackPageViews /> to your root layout inside a <Suspense> boundary (required by useSearchParams):
// app/layout.tsx (body section)
import { Suspense } from 'react';
import { TrackPageViews } from '@/components/track-page-views';
<body>
<Suspense fallback={null}>
<TrackPageViews />
</Suspense>
{children}
</body>Pages Router
Add the snippet to _app.tsx and track route changes with the Next.js router:
// pages/_app.tsx
import type { AppProps } from 'next/app';
import Script from 'next/script';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter();
useEffect(() => {
const handleRouteChange = () => {
if (typeof window.vendo === 'function') {
window.vendo('page');
}
};
router.events.on('routeChangeComplete', handleRouteChange);
return () => router.events.off('routeChangeComplete', handleRouteChange);
}, [router.events]);
return (
<>
<Script id="vendo-tracking" strategy="afterInteractive">
{`
(function(w,d,s,e,l,k){w['VendoObject']=e;w[e]=w[e]||function(){
(w[e].q=w[e].q||[]).push(arguments)};w[e].l=1*new Date();
l=d.createElement(s);k=d.getElementsByTagName(s)[0];
l.async=1;l.src='https://cdn.vendodata.com/sdk/v1/vendo.js';k.parentNode.insertBefore(l,k);
})(window,document,'script','vendo');
vendo('init', 'YOUR_WRITE_KEY', {
host: 'https://YOUR_TRACKING_ENDPOINT',
trackPageViews: true
});
`}
</Script>
<Component {...pageProps} />
</>
);
}Identify Users
Call identify once the user is authenticated:
window.vendo('identify', user.id, {
email: user.email,
name: user.name,
plan: user.plan,
});Call reset on logout to clear the identity:
window.vendo('reset');Related
- JavaScript SDK — Full method reference and configuration options
- Quickstart — Get started in 5 minutes
Last updated on