# Next.js web analytics installation - Docs

1.  1

    ## Install the package

    Required

    Install the PostHog JavaScript library using your package manager:

    PostHog AI

    ### npm

    ```bash
    npm install posthog-js
    ```

    ### yarn

    ```bash
    yarn add posthog-js
    ```

    ### pnpm

    ```bash
    pnpm add posthog-js
    ```

2.  2

    ## Add environment variables

    Required

    Add your PostHog project token and host to your `.env.local` file and to your hosting provider (e.g. Vercel, Netlify). These values need to start with `NEXT_PUBLIC_` to be accessible on the client-side.

    .env.local

    PostHog AI

    ```bash
    NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN=<ph_project_token>
    NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
    ```

3.  3

    ## Initialize PostHog

    Required

    Choose the integration method based on your Next.js version and router type.

    ## Next.js 15.3+

    If you're using Next.js 15.3+, you can use `instrumentation-client.ts` for a lightweight, fast integration:

    instrumentation-client.ts

    PostHog AI

    ```typescript
    import posthog from 'posthog-js'
    posthog.init(process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN!, {
        api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
        defaults: '2026-01-30'
    })
    ```

    ## App router

    For the App router, create a `providers.tsx` file in your `app` folder. The `posthog-js` library needs to be initialized on the client-side using the `'use client'` directive:

    app/providers.tsx

    PostHog AI

    ```typescript
    'use client'
    import { usePathname, useSearchParams } from "next/navigation"
    import { useEffect } from "react"
    import posthog from 'posthog-js'
    import { PostHogProvider as PHProvider } from 'posthog-js/react'
    export function PostHogProvider({ children }: { children: React.ReactNode }) {
      useEffect(() => {
        posthog.init(process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN as string, {
          api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
          defaults: '2026-01-30'
        })
      }, [])
      return (
        <PHProvider client={posthog}>
          {children}
        </PHProvider>
      )
    }
    ```

    Then import the `PostHogProvider` component in your `app/layout.tsx` and wrap your app with it:

    app/layout.tsx

    PostHog AI

    ```typescript
    import './globals.css'
    import { PostHogProvider } from './providers'
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <body>
            <PostHogProvider>
              {children}
            </PostHogProvider>
          </body>
        </html>
      )
    }
    ```

    ## Pages router

    For the Pages router, integrate PostHog at the root of your app in `pages/_app.tsx`:

    pages/\_app.tsx

    PostHog AI

    ```typescript
    import { useEffect } from 'react'
    import { Router } from 'next/router'
    import posthog from 'posthog-js'
    import { PostHogProvider } from 'posthog-js/react'
    import type { AppProps } from 'next/app'
    export default function App({ Component, pageProps }: AppProps) {
      useEffect(() => {
        posthog.init(process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN as string, {
          api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
          defaults: '2026-01-30',
          loaded: (posthog) => {
            if (process.env.NODE_ENV === 'development') posthog.debug()
          }
        })
      }, [])
      return (
        <PostHogProvider client={posthog}>
          <Component {...pageProps} />
        </PostHogProvider>
      )
    }
    ```

    **Defaults option**

    The `defaults` option automatically configures PostHog with recommended settings for new projects. See [SDK defaults](/docs/libraries/js.md#sdk-defaults) for details.

4.  4

    ## Accessing PostHog on the client

    Recommended

    ## Next.js 15.3+

    Once initialized in `instrumentation-client.ts`, import `posthog` from `posthog-js` anywhere and call the methods you need:

    app/checkout/page.tsx

    PostHog AI

    ```typescript
    'use client'
    import posthog from 'posthog-js'
    export default function CheckoutPage() {
        function handlePurchase() {
            posthog.capture('purchase_completed', { amount: 99 })
        }
        return <button onClick={handlePurchase}>Complete purchase</button>
    }
    ```

    ## App/Pages router

    Use the `usePostHog` hook to access PostHog in client components:

    app/checkout/page.tsx

    PostHog AI

    ```typescript
    'use client'
    import { usePostHog } from 'posthog-js/react'
    export default function CheckoutPage() {
        const posthog = usePostHog()
        function handlePurchase() {
            posthog.capture('purchase_completed', { amount: 99 })
        }
        return <button onClick={handlePurchase}>Complete purchase</button>
    }
    ```

5.  5

    ## Server-side setup

    Optional

    To capture events from API routes or server actions, install `posthog-node`:

    PostHog AI

    ### npm

    ```bash
    npm install posthog-node
    ```

    ### yarn

    ```bash
    yarn add posthog-node
    ```

    ### pnpm

    ```bash
    pnpm add posthog-node
    ```

    Then, initialize PostHog in your API route or server action. Choose the method based on your router type:

    ## App router

    For the App router, you can use PostHog in API routes or server actions. Create a new PostHog client instance for each request, or reuse a singleton instance across requests:

    app/api/example/route.ts

    PostHog AI

    ```typescript
    import { PostHog } from 'posthog-node'
    export async function POST(request: Request) {
        const posthog = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN!, {
            host: process.env.NEXT_PUBLIC_POSTHOG_HOST
        })
        posthog.capture({
            distinctId: 'distinct_id_of_the_user',
            event: 'event_name'
        })
        await posthog.shutdown()
    }
    ```

    You can also use PostHog in server actions:

    app/actions.ts

    PostHog AI

    ```typescript
    'use server'
    import { PostHog } from 'posthog-node'
    export async function myServerAction() {
        const posthog = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN!, {
            host: process.env.NEXT_PUBLIC_POSTHOG_HOST
        })
        posthog.capture({
            distinctId: 'distinct_id_of_the_user',
            event: 'server_action_completed'
        })
        await posthog.shutdown()
    }
    ```

    ## Pages router

    For the Pages router, use PostHog in your API routes:

    pages/api/example.ts

    PostHog AI

    ```typescript
    import { PostHog } from 'posthog-node'
    import type { NextApiRequest, NextApiResponse } from 'next'
    export default async function handler(
        req: NextApiRequest,
        res: NextApiResponse
    ) {
        const posthog = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN!, {
            host: process.env.NEXT_PUBLIC_POSTHOG_HOST
        })
        posthog.capture({
            distinctId: 'distinct_id_of_the_user',
            event: 'event_name'
        })
        await posthog.shutdown()
        res.status(200).json({ success: true })
    }
    ```

    **Important**

    Always call `await posthog.shutdown()` when you're done with the client to ensure all events are flushed before the request completes. For better performance, consider creating a singleton PostHog instance that you reuse across requests.

6.  6

    ## Send events

    Recommended

    Click around and view a couple pages to generate some events. PostHog automatically captures pageviews, clicks, and other interactions for you.

    If you'd like, you can also manually capture custom events:

    JavaScript

    PostHog AI

    ```javascript
    posthog.capture('my_custom_event', { property: 'value' })
    ```

7.  7

    ## Next steps

    Recommended

    After installing PostHog and ensuring [autocapture](/docs/data/autocapture.md) is enabled, head to your [web analytics dashboard](/docs/web-analytics/dashboard.md) to see your data. And then check out our [getting started](/docs/web-analytics/getting-started.md) guide.

    > **PostHog tip:** Web analytics works with [anonymous events](/docs/data/anonymous-vs-identified-events.md). This means if you are primarily using PostHog for web analytics, it can be significantly cheaper for you.

### Community questions

Ask a question

### Was this page useful?

HelpfulCould be better