Docs
Browse the docs

Add Privatus Analytics to Next.js

Add cookieless analytics to Next.js with @privatus/next or next/script, for the App or Pages Router, with server-side events.

View as Markdown

Warning: @privatus/next is not published on npm yet. Until it is, don't install a package with this name from the public registry, because anyone could have published it. Use the setup under Without the package instead.

sh
npm install @privatus/next

1. Add the component#

App Router, in app/layout.tsx:

tsx
import { PrivatusAnalytics } from '@privatus/next'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <PrivatusAnalytics site="pa_YOURSITEID" modules={['engage', 'auto']} />
      </body>
    </html>
  )
}

Pages Router: render the same component in pages/_app.tsx.

The component takes every tracker option as a typed prop (spa, manual, modules, domains, exclude, mask, params, canonical, hash…). It loads the script from privatusanalytics.com and sends hits there.

2. Track events#

tsx
'use client'
import { usePrivatus } from '@privatus/next'

export function UpgradeButton() {
  const privatus = usePrivatus()
  return <button onClick={() => privatus.track('Upgrade', { plan: 'pro' })}>Upgrade</button>
}

trackAsync(name, props, timeout) returns a promise that resolves when the hit is sent (or after the timeout), which is handy before a redirect.

Server-side events#

Track from route handlers, server actions or middleware with a secret ingest key in PRIVATUS_INGEST_KEY:

ts
// app/api/signup/route.ts
import { trackEvent } from '@privatus/next/server'

export async function POST(request: Request) {
  // … create the account …
  await trackEvent(request, { name: 'Signup', props: { plan: 'pro' } })
  return Response.json({ ok: true })
}

The helper forwards the visitor's IP and User-Agent from the request in the body (used in memory only, never stored) and works in the Edge and Node.js runtimes.

Without the package#

Use next/script in the root layout:

tsx
import Script from 'next/script'

<Script defer src="https://privatusanalytics.com/js/pa.js" data-site="pa_YOURSITEID" strategy="afterInteractive" />

Next.js client navigations use history.pushState, which the tracker follows with its default data-spa="auto".