---
title: "Next.js"
description: "Set up Middleware APM for Next.js apps to get deep visibility into performance metrics, errors, and application health."
section: "APM"
breadcrumb: "APM > Next.JS"
canonical: "https://docs.middleware.io/get-started/apm/nextjs"
---
# Next.js

Use the Middleware Next.js APM package to collect traces, metrics and application logs from server components, API routes and middleware in a Next.js app. The table shows which data types it collects.

| Traces | Metrics | App Logs | Custom Logs | Profiling |
| --- | --- | --- | --- | --- |
| ✅ | ✖ | ✖ | ✅ | ✅ |

## 1. Prerequisites

- Next.js 13.4+ (instrumentation file support). Check:

  ```javascript
      npx next --version
  ```
- Enable the instrumentation hook. In Next.js, the `instrumentation.ts` file is wired via the experimental `instrumentationHook` flag (still documented as experimental).
- OpenTelemetry API peer range (required by the agent):

  ```javascript
      npm i @opentelemetry/api@">=1.3.0 <1.5.0"
  ```
- (Optional but recommended) Middleware Host Agent on the same host/cluster. In containers, set `MW_AGENT_SERVICE` so your app can reach the agent:

  - Docker: `MW_AGENT_SERVICE=172.17.0.1`
  - Kubernetes: `MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local`

## 2. Install the Next.js APM package

```bash
    npm install @middleware.io/agent-apm-nextjs
```

## 3. Modify next.config.js

Add the instrumentation flag. For newer projects, it’s also recommended to allow the package in server components’ externals:

```javascript
    // next.config.js
const nextConfig = {
  experimental: {
    instrumentationHook: true,
    // recommended on modern projects
    serverComponentsExternalPackages: ['@middleware.io/agent-apm-nextjs'],
  },
};
module.exports = nextConfig;
```

This mirrors the package guidance and Next.js’ own docs on enabling the instrumentation hook.

## 4. Create the instrumentation file

Place `instrumentation.ts` (or `.js`) at the project root (or inside `src/` if you use a `src` directory). The file must export a `register()` function as Next.js calls it once when a server instance boots.

With Host Agent (default path):

```javascript
    // instrumentation.ts
// @ts-expect-error: type declarations are not yet complete
import tracker from '@middleware.io/agent-apm-nextjs';

export function register() {
  tracker.track({
    serviceName: '{APM-SERVICE-NAME}',
    accessToken: 'your-initial-token',
  });
}
```

Serverless / no Host Agent (send direct to Middleware):

```javascript
    // instrumentation.ts
import tracker from '@middleware.io/agent-apm-nextjs';

export function register() {
  tracker.track({
    serviceName: '{APM-SERVICE-NAME}',
    accessToken: 'your-initial-token',
    target: 'your-initial-uid',
  });
}
```

If you customise `pagesExtension`, ensure the filename matches (e.g., `instrumentation.ts`).

## 5. Container variables (only if using the Host Agent)

Docker

```bash
    MW_AGENT_SERVICE=172.17.0.1
```

- (`172.17.0.1` is Docker’s default bridge gateway.)

Kubernetes

```bash
    MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local
```

You can locate the service with:

```bash
    kubectl get service --all-namespaces | grep mw-service
```

## 6. Enable custom logs (optional)

Use the logger helpers anywhere in your API routes, Route Handlers, or server actions:

```javascript
    // @ts-expect-error
import tracker from '@middleware.io/agent-apm-nextjs';

export default async function handler(req, res) {
  tracker.info('Info Sample');
  tracker.warn('Warn Sample', { tester: 'Alex' });
  tracker.debug('Debug Sample');
  tracker.error('Error Sample');
  // ...
}
```

## 7. View your Data

After deploy/startup, wait 3–5 minutes and then open [APM → Traces](https://app.middleware.io/apm/traces), Logs, and [APM → Continuous Profiling](https://app.middleware.io/apm/profiling) in your Middleware account. (For Next.js, metrics and app-logs are not collected by this agent; use Custom Logs as shown above.)

## 8. Environment variables

These mirror the options you’d otherwise pass in `tracker.track(...)`.

| Variable | Purpose | Example |
| --- | --- | --- |
| `MW_API_KEY` | Authentication token for exports. | `xxxxxxxx…` |
| `MW_TARGET` | OTLP endpoint (serverless/remote). Defaults to Host Agent when omitted. | `https://<MW_UID>.middleware.io:443` |
| `MW_SERVICE_NAME` | APM service identifier. | `nextjs-web` |
| `MW_PROJECT_NAME` | Logical project/app name (optional). | `ShopApp` |
| `MW_CONSOLE_EXPORTER` | Echo spans/logs to the console for local verification. | `true` |
| `MW_AGENT_SERVICE` | Host/Service for the Agent when in containers. | `172.17.0.1` or `mw-service.mw-agent-ns.svc.cluster.local` |

## 9. Troubleshooting quick checks

- `register()` didn’t run / no traces: ensure `experimental.instrumentationHook: true` is set and the file is named and placed correctly (root or `src/`).
- On Vercel builds: also include serverComponentsExternalPackages: `['@middleware.io/agent-apm-nextjs']` as recommended by the package and Vercel integration notes.
- Container reachability: set `MW_AGENT_SERVICE` as shown above.

Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us page or join our Slack channel.
