# 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.

## With `@privatus/next` (recommended)

> **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](#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](/docs/server-side/ingest-keys) 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"`.
