Next.js

Integration for Next.js 13+ with App Router or Pages Router.

Recommended: npm package

Use our official @savri/tracker package for the best Next.js integration with TypeScript support and React hooks.

View full SDK documentation

Using @savri/tracker (Recommended)

1. Install the package

npm install @savri/tracker

2a. App Router (Next.js 13+)

Add the provider to your root layout:

app/layout.tsx

import { SavriProvider } from '@savri/tracker/react'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <SavriProvider siteId={process.env.NEXT_PUBLIC_SAVRI_SITE_ID!}>
          {children}
        </SavriProvider>
      </body>
    </html>
  )
}

2b. Pages Router

Add the provider to _app.tsx:

pages/_app.tsx

import { SavriProvider } from '@savri/tracker/react'
import type { AppProps } from 'next/app'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <SavriProvider siteId={process.env.NEXT_PUBLIC_SAVRI_SITE_ID!}>
      <Component {...pageProps} />
    </SavriProvider>
  )
}

3. Track events

Use the useTracker hook in any client component:

'use client'

import { useTracker } from '@savri/tracker/react'

export function SignupButton() {
  const { trackEvent } = useTracker()

  const handleClick = () => {
    trackEvent('Signup Click', { plan: 'pro' })
  }

  return (
    <button onClick={handleClick}>
      Sign up
    </button>
  )
}

Alternative: Script tag

If you prefer not to use npm, you can use Next.js Script component.

App Router with Script

app/layout.tsx

import Script from 'next/script'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <head>
        <Script
          defer
          data-site-id="YOUR-SITE-ID"
          data-api="https://savri.io"
          src="https://savri.io/script.js"
          strategy="afterInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  )
}

Pages Router with Script

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="YOUR-SITE-ID"
        data-api="https://savri.io"
        src="https://savri.io/script.js"
        strategy="afterInteractive"
      />
      <Component {...pageProps} />
    </>
  )
}

Production only

If you only want to track in production:

// With npm package
<SavriProvider
  siteId={process.env.NEXT_PUBLIC_SAVRI_SITE_ID!}
  disabled={process.env.NODE_ENV !== 'production'}
>

// Or with script tag
{process.env.NODE_ENV === 'production' && (
  <Script ... />
)}

Content Security Policy (CSP)

If your site uses CSP, you need to allow savri.io 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.

Read more about CSP configuration