---
title: "Send OpenTelemetry from Next.js to your Mac"
description: "Add instrumentation.ts, point OTEL_EXPORTER_OTLP_ENDPOINT at the Loggerhead receiver, and read the traces and metrics of your Next.js app in one window."
source: "https://getloggerhead.com/docs/send-telemetry/nextjs/"
---

# Send OpenTelemetry from Next.js to your Mac

> Add instrumentation.ts, point OTEL_EXPORTER_OTLP_ENDPOINT at the Loggerhead receiver, and read the traces and metrics of your Next.js app in one window.

Next.js has OpenTelemetry support built in. One file and two environment variables send its traces to Loggerhead. One more package sends its metrics too.

## Before you start

- Loggerhead is open.
- You know the effective port. Open **Collectors → Loggerhead receiver → Connection** and copy the HTTP port. The first workspace uses 4318. See [Ports and the effective port](/docs/getting-started/ports-and-the-effective-port/).

## Step 1: install the package

```bash
npm install @vercel/otel @opentelemetry/api
```

## Step 2: add instrumentation.ts

Save this file as `instrumentation.ts` in the root of the project, beside `app/`. Next.js loads it before anything else.

```ts title="instrumentation.ts"
import { registerOTel } from '@vercel/otel';

export function register() {
  registerOTel({ serviceName: 'my-next-app' });
}
```

:::note[Next.js 14 and older]
Next.js 15 loads the file by itself. On 13 and 14, add `experimental: { instrumentationHook: true }` to `next.config.js`.
:::

## Step 3: set the endpoint

```bash title=".env.local"
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
```

Start the app with `npm run dev` and open a page that reads data.

## Step 4: send metrics too

`registerOTel` exports traces only. Give it a metric reader, and the counters and histograms that your code records with the OpenTelemetry API go to Loggerhead as well.

```bash
npm install @opentelemetry/sdk-metrics @opentelemetry/exporter-metrics-otlp-proto
```

```ts title="instrumentation.ts"
import { registerOTel } from '@vercel/otel';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';

export function register() {
  registerOTel({
    serviceName: 'my-next-app',
    metricReaders: [
      new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter(), exportIntervalMillis: 10_000 }),
    ],
  });
}
```

The exporter reads the same `OTEL_EXPORTER_OTLP_ENDPOINT`.

## What arrives

| Signal | State |
| --- | --- |
| Traces | Every request, with the render and the fetch calls inside it. |
| Metrics | Only with the metric reader of step 4: the metrics your code records. Next.js and `@vercel/otel` record none by themselves. |
| Logs | Not from this package. Send them through a branch collector, or add an OTLP log exporter. |

## Tag the environment

A record with no tag lands in the Local environment. To send a deployment somewhere else, name it:

```bash
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=staging
```

See [Workspaces and environments](/docs/getting-started/workspaces-and-environments/).

## Then read it with your agent

1. Open **Logs** or **Traces** in Loggerhead. New records arrive while the page is live.
2. Connect your coding agent once, and it reads the same data. See [Claude Code](/docs/connect-your-ai-tool/claude-code/).
