Ops AI Next.js APM

Instrument your Next.js app with the Middleware Next.js SDK so Ops AI can analyze production issues and (when applicable) propose solution PRs.

You’ll learn how to: (1) install the APM + sourcemap uploader, (2) update next.config.js to build & upload sourcemaps, and (3) add an instrumentation file.

Delivery Modes (choose one)#

  • With Infra Agent: The SDK sends telemetry to the mw-agent on the host, and the agent forwards it to the Middleware. Route: SDK → mw-agent → Middleware.
  • Without Infra agent: The SDK sends directly to the Middleware over HTTPS. Route: SDK → Middleware (set target: "https://<MW_UID>.middleware.io:443").
  • Vercel: You don’t control the underlying server, so you can’t install mw-agent. The SDK sends to a Vercel integration, which forwards to Middleware. Route: SDK → vercel-integration → Middleware (target: "vercel").

1. Install the APM + Sourcemap Uploader (Bash)#

Add the Next.js APM package and sourcemap uploader to your project.

npm i @middleware.io/agent-apm-nextjs @middleware.io/sourcemap-uploader

2. Update next.config.js#

This enables production browser source maps and configures the middleware source map uploader. Replace "<ACCOUNT-KEY>" with your app’s key. If you’re using Next.js < 14.0, remove the serverComponentsExternalPackages line if it exists in your project.

// next.config.js
const MiddlewareWebpackPlugin =
  require("@middleware.io/sourcemap-uploader/dist/webpack-plugin").default;

const nextConfig = {
  // ...your existing config
  productionBrowserSourceMaps: true, // for client-side sourcemaps

  webpack: (config, { isServer }) => {
    config.plugins.push(
      new MiddlewareWebpackPlugin(
        "<ACCOUNT-KEY>" // Account key of the application.
      )
    );
    return config;
  },
};

module.exports = nextConfig;

Why this matters: Sourcemaps enable Ops AI to resolve minified stack traces back to readable source code during error analysis.

3. Create instrumentation.ts#

Create instrumentation.ts (or .js) in your project root (or under src/). Then pick one of the three variants below that matches your delivery mode.

A. Without Infra Agent (no target)#

The SDK sends the data to the mw-agent on the host; the agent forwards it to the Middleware. Do not set the target.

// instrumentation.ts
// @ts-expect-error: The NextJS APM does not currently have full type declarations
import tracker from '@middleware.io/agent-apm-nextjs';

export function register() {
  tracker.track({
    serviceName: "<SERVICE-NAME>",
    accessToken: "<MW_API_KEY>",
    enableExceptionHandling: true,
    customResourceAttributes: {
      "app.version": "<1.0.0>"
    }
  });
}

B. With Infra Agent (direct to Middleware)#

Set target to your workspace URL so the SDK ships directly to Middleware.

// instrumentation.ts
// @ts-expect-error: The NextJS APM does not currently have full type declarations
import tracker from '@middleware.io/agent-apm-nextjs';

export function register() {
  tracker.track({
    serviceName: "<SERVICE-NAME>",
    accessToken: "<MW_API_KEY>",
    target: "https://<MW_UID>.middleware.io:443",
    enableExceptionHandling: true,
    customResourceAttributes: {
      "app.version": "1.0.0"
    }
  });
}

C. Vercel Deployment (send to Vercel integration)#

Use target: "vercel" so the SDK forwards to the Vercel integration, which then ships to Middleware.

// instrumentation.ts
// @ts-expect-error: The NextJS APM does not currently have full type declarations
import tracker from '@middleware.io/agent-apm-nextjs';

export function register() {
  tracker.track({
    serviceName: "<SERVICE-NAME>",
    accessToken: "<MW_API_KEY>",
    target: "vercel",
    enableExceptionHandling: true,
    customResourceAttributes: {
      "app.version": "1.0.0"
    }
  });
}

Manual Exception Capture (pages router)#

If you use the Pages router, manually capture thrown errors so they’re visible in Ops AI.

// @ts-ignore
import tracker from '@middleware.io/agent-apm-nextjs';

try {
  // Code that might throw
  riskyOperation();
} catch (error) {
  tracker.captureException(error);
}

(Recommended) VCS Metadata (Bash)#

If a .git directory isn’t present at runtime (e.g., container builds), set these so Ops AI can tie incidents to the correct repo/commit for code mapping and PR suggestions.

MW_VCS_COMMIT_SHA=$(git rev-parse HEAD)
MW_VCS_REPOSITORY_URL=$(git config --get remote.origin.url)

These are just example commands to fetch values from Git. You can set these environment variables in any way that fits your workflow, such as through your CI/CD pipeline or other automation tools.

Need assistance or want to learn more about Middleware? Contact our support team at [email protected] or join our Slack channel.