Next.js error tracking installation

  1. Install the package

    Required

    Install the PostHog JavaScript library using your package manager:

    npm install posthog-js
  2. Add environment variables

    Required

    Add your PostHog API key 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
    NEXT_PUBLIC_POSTHOG_KEY=<ph_project_api_key>
    NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
  3. Initialize PostHog

    Required

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

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

    instrumentation-client.ts
    import posthog from 'posthog-js'
    posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
    api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
    defaults: '2026-01-30'
    })
    Defaults option

    The defaults option automatically configures PostHog with recommended settings for new projects. See SDK defaults for details.

  4. Accessing PostHog on the client

    Recommended

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

    app/checkout/page.tsx
    '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>
    }
  5. Capture client-side exceptions

    Required

    PostHog can automatically capture unhandled exceptions in your Next.js app using the JavaScript Web SDK.

    You can enable exception autocapture for the JavaScript Web SDK in the Error tracking section of your project settings.

    It is also possible to manually capture exceptions using the captureException method:

    JavaScript
    posthog.captureException(error, additionalProperties)
    Manual capture is very useful if you already use error boundaries to handle errors in your app:

    Next.js uses error boundaries to handle uncaught exceptions by rendering a fallback UI instead of the crashing components. To set one up, create a error.tsx file in any of your route directories. This triggers when there is an error rendering your component and should look like this:

    error.tsx
    "use client"
    import posthog from "posthog-js"
    import { useEffect } from "react"
    export default function Error({
    error,
    reset,
    }: {
    error: Error & { digest?: string }
    reset: () => void
    }) {
    useEffect(() => {
    posthog.captureException(error)
    }, [error])
    return (
    ...
    )
    }

    You can also create a Global Error component in your root layout to capture unhandled exceptions in your root layout.

    app/global-error.tsx
    'use client'
    import posthog from "posthog-js"
    import NextError from "next/error"
    import { useEffect } from "react"
    export default function GlobalError({
    error,
    reset,
    }: {
    error: Error & { digest?: string }
    reset: () => void
    }) {
    useEffect(() => {
    posthog.captureException(error)
    }, [error])
    return (
    // global-error must include html and body tags
    <html>
    <body>
    {/* `NextError` is the default Next.js error page component */}
    <NextError statusCode={0} />
    </body>
    </html>
    )
    }
  6. Installing PostHog SDK for server-side

    Required

    Next.js enables you to both server-side render pages and add server-side functionality. To integrate PostHog into your Next.js app on the server-side, you can use the Node SDK.

    First, install the posthog-node library:

    npm install posthog-node --save

    For the backend, we can create a lib/posthog-server.js file. In it, initialize PostHog from posthog-node as a singleton with your project API key and host from your project settings.

    This looks like this:

    lib/posthog-server.js
    import { PostHog } from 'posthog-node'
    let posthogInstance = null
    export function getPostHogServer() {
    if (!posthogInstance) {
    posthogInstance = new PostHog(
    process.env.NEXT_PUBLIC_POSTHOG_KEY,
    {
    host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
    flushAt: 1,
    flushInterval: 0,
    }
    )
    }
    return posthogInstance
    }

    You can now use the getPostHogServer function to capture exceptions in server-side code.

    JavaScript
    const posthog = getPostHogServer()
    try {
    throw new Error("This is a test exception for error tracking")
    } catch (error) {
    posthog.captureException(error, {
    source: 'test',
    user_id: 'test-user-123',
    })
    }
  7. Verify server-side exceptions

    Recommended

    You should also see events and exceptions in PostHog coming from your server-side code in the activity feed.

    Check for server events in PostHog

  8. Capturing server-side exceptions

    Required

    To capture errors that occur in your server-side code, you can set up an instrumentation.ts file at the root of your project. This provides a onRequestError hook that you can use to capture errors.

    Importantly, you need to:

    1. Set up a posthog-node client in your server-side code. See our doc on setting up Next.js server-side analytics for more.
    2. Check the request is running in the nodejs runtime to ensure PostHog works. You can call posthog.debug() to get verbose logging.
    3. Get the distinct_id from the cookie to connect the error to a specific user.

    This looks like this:

    JavaScript
    // instrumentation.js
    export function register() {
    // No-op for initialization
    }
    export const onRequestError = async (err, request, context) => {
    if (process.env.NEXT_RUNTIME === 'nodejs') {
    const { getPostHogServer } = require('./lib/posthog-server')
    const posthog = getPostHogServer()
    let distinctId = null
    if (request.headers.cookie) {
    // Normalize multiple cookie arrays to string
    const cookieString = Array.isArray(request.headers.cookie)
    ? request.headers.cookie.join('; ')
    : request.headers.cookie
    const postHogCookieMatch = cookieString.match(/ph_phc_.*?_posthog=([^;]+)/)
    if (postHogCookieMatch && postHogCookieMatch[1]) {
    try {
    const decodedCookie = decodeURIComponent(postHogCookieMatch[1])
    const postHogData = JSON.parse(decodedCookie)
    distinctId = postHogData.distinct_id
    } catch (e) {
    console.error('Error parsing PostHog cookie:', e)
    }
    }
    }
    await posthog.captureException(err, distinctId || undefined)
    }
    }

    You can find a full example of both this and client-side error tracking in our Next.js error monitoring tutorial.

  9. Verify error tracking

    Recommended
    Confirm events are being sent to PostHog
    Before proceeding, let's make sure exception events are being captured and sent to PostHog. You should see events appear in the activity feed.
    Activity feed with events
    Check for exceptions in PostHog

Community questions

Was this page useful?

Questions about this page? or post a community question.