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.tsfile is wired via the experimentalinstrumentationHookflag (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_SERVICEso 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
- Docker:
2. Install the Next.js APM package#
npm install @middleware.io/agent-apm-nextjs3. Modify next.config.js#
Add the instrumentation flag. For newer projects, it’s also recommended to allow the package in server components’ externals:
// 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):
// 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: '<MW_API_KEY>',
});
}Serverless / no Host Agent (send direct to Middleware):
// instrumentation.ts
import tracker from '@middleware.io/agent-apm-nextjs';
export function register() {
tracker.track({
serviceName: '{APM-SERVICE-NAME}',
accessToken: '<MW_API_KEY>',
target: 'https://<MW_UID>.middleware.io:443',
});
}If you customise pagesExtension, ensure the filename matches (e.g., instrumentation.ts).
5. Container variables (only if using the Host Agent)#
Docker
MW_AGENT_SERVICE=172.17.0.1- (
172.17.0.1is Docker’s default bridge gateway.)
Kubernetes
MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.localYou can locate the service with:
kubectl get service --all-namespaces | grep mw-service6. Enable custom logs (optional)#
Use the logger helpers anywhere in your API routes, Route Handlers, or server actions:
// @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, 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(...).
| 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: ensureexperimental.instrumentationHook: trueis set and the file is named and placed correctly (root orsrc/).- 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_SERVICEas shown above.
Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us or join our Slack channel.
What did you think of this content?