Skip to content

Next.js

Next.js can emit server-side OpenTelemetry through @vercel/otel. Use @pydantic/logfire-browser with a restricted frontend application token for client-side browser traces.

Server-Side Tracing

Install Vercel’s OpenTelemetry package and the manual logfire API if you want to create spans in React Server Components, route handlers, or server actions:

Terminal
npm install @vercel/otel logfire

Create instrumentation.ts in your project root or src directory:

instrumentation.ts
import { registerOTel } from '@vercel/otel'

export function register() {
  registerOTel({
    serviceName: 'nextjs-app',
  })
}

Set OTLP export to Logfire:

.env.local
OTEL_EXPORTER_OTLP_ENDPOINT=https://logfire-api.pydantic.dev
OTEL_EXPORTER_OTLP_HEADERS='Authorization=your-write-token'

Then use the manual API where useful:

import * as logfire from 'logfire'

export default async function Page() {
  return logfire.span('render home page', {
    callback: async () => {
      logfire.info('loading homepage data')
      return <main>Hello</main>
    },
  })
}

Vercel production deployments can cache build and runtime configuration. If spans do not appear after changing tracing environment variables, clear the Vercel data cache for the project and redeploy.

Client-Side Tracing

Install the browser package:

Terminal
npm install @pydantic/logfire-browser @opentelemetry/auto-instrumentations-web

Create a frontend application under Project settings > Frontend applications, then copy its generated browser setup. The token can only write telemetry for that frontend application and cannot read project data. Follow the Frontend guide for setup and verification.

For Next.js 15.3 and later, configure the browser package in instrumentation-client.ts using the generated traceUrl and traceExporterHeaders values. Next.js loads this file once in the browser before the application becomes interactive.

instrumentation-client.ts
import * as logfire from '@pydantic/logfire-browser'

logfire.configure({
  traceUrl: 'https://logfire-us.pydantic.dev/v1/traces',
  traceExporterHeaders: () => ({
    Authorization: 'Bearer <frontend-application-token>',
  }),
  autoInstrumentations: true,
})

Optional Proxy

Use a proxy route or middleware if you need to authenticate browser requests, restrict origins, or apply application-specific rate limits.

For Next.js 16 and later, place this code in proxy.ts in the project root, or in src/proxy.ts if your app uses src.

Store the write token in a server-only environment variable such as LOGFIRE_TOKEN. Do not use a NEXT_PUBLIC_ variable for the token.

proxy.ts
import { NextRequest, NextResponse } from 'next/server'

export default function proxy(request: NextRequest) {
  const url = request.nextUrl.clone()

  if (url.pathname === '/logfire-proxy/v1/traces') {
    const requestHeaders = new Headers(request.headers)
    requestHeaders.set('Authorization', process.env.LOGFIRE_TOKEN!)

    return NextResponse.rewrite(new URL(process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ?? 'https://logfire-api.pydantic.dev/v1/traces'), {
      request: {
        headers: requestHeaders,
      },
    })
  }
}

export const config = {
  matcher: '/logfire-proxy/:path*',
}

Then point instrumentation-client.ts at the proxy:

instrumentation-client.ts
import * as logfire from '@pydantic/logfire-browser'

logfire.configure({
  traceUrl: '/logfire-proxy/v1/traces',
  serviceName: 'nextjs-browser',
  autoInstrumentations: true,
})

See examples/nextjs and examples/nextjs-client-side-instrumentation for working projects.