Next.js

TracesMetricsApp LogsCustom LogsProfiling

1. Prerequisites

  • Next.js 13.4+ (instrumentation file support). Check:
    1npx 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):
    1npm 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

1npm 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:

1// next.config.js
2const nextConfig = {
3  experimental: {
4    instrumentationHook: true,
5    // recommended on modern projects
6    serverComponentsExternalPackages: ['@middleware.io/agent-apm-nextjs'],
7  },
8};
9module.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):

1// instrumentation.ts
2// @ts-expect-error: type declarations are not yet complete
3import tracker from '@middleware.io/agent-apm-nextjs';
4
5export function register() {
6  tracker.track({
7    serviceName: '{APM-SERVICE-NAME}',
8    accessToken: '<MW_API_KEY>',
9  });
10}

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

1// instrumentation.ts
2import tracker from '@middleware.io/agent-apm-nextjs';
3
4export function register() {
5  tracker.track({
6    serviceName: '{APM-SERVICE-NAME}',
7    accessToken: '<MW_API_KEY>',
8    target: 'https://<MW_UID>.middleware.io:443',
9  });
10}

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

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

Docker

1MW_AGENT_SERVICE=172.17.0.1
  • (172.17.0.1 is Docker’s default bridge gateway.)

Kubernetes

1MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local

You can locate the service with:

1kubectl 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:

1// @ts-expect-error
2import tracker from '@middleware.io/agent-apm-nextjs';
3
4export default async function handler(req, res) {
5  tracker.info('Info Sample');
6  tracker.warn('Warn Sample', { tester: 'Alex' });
7  tracker.debug('Debug Sample');
8  tracker.error('Error Sample');
9  // ...
10}

7. View your Data

After deploy/startup, wait 3–5 minutes and then open APM → Traces, Logs, and APM → Continuous 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(...).

VariablePurposeExample
MW_API_KEYAuthentication token for exports.xxxxxxxx…
MW_TARGETOTLP endpoint (serverless/remote). Defaults to Host Agent when omitted.https://<MW_UID>.middleware.io:443
MW_SERVICE_NAMEAPM service identifier.nextjs-web
MW_PROJECT_NAMELogical project/app name (optional).ShopApp
MW_CONSOLE_EXPORTEREcho spans/logs to the console for local verification.true
MW_AGENT_SERVICEHost/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? Contact our support team at [email protected] or join our Slack channel.