Next.js

Track AI agents in your Next.js app

One line in middleware.ts. Works on any host, in Edge or Node, and only agent requests cost you anything.

Why you can't see them today

Your analytics is a client component. An agent fetches the server-rendered HTML and leaves — no hydration, no JavaScript, no event. The request is in your logs and nowhere in your dashboard.

The reason there's no script tag to paste. AI agents don't execute JavaScript. Every analytics tool you already run is a browser tag, so it never fires for an agent — which is why your dashboards show none of this traffic. The only way to see it is server-side, at the edge, or in your logs.

See yours before you install anything

Paste a chunk of your access log and we'll pull out the AI agents that crawled you, what they read, and the files they asked for and couldn't find. No account, nothing stored.

Check my log free →

Install: Middleware

One line of code. Doesn't capture response status — see the gotchas below.

  1. Install the collector. It's dependency-free and MIT licensed.
    npm i @pickrate/collector
  2. Re-export the middleware. If you don't have a middleware.ts yet, this is the whole file.
    // middleware.ts
    export { middleware } from "@pickrate/collector/next";
    export const config = { matcher: ["/((?!_next|favicon).*)"] };
  3. Set your key. Add PICKRATE_KEY to your environment with a secret (sk_) key from Pickrate Settings. With no key set, the collector is a no-op — your app behaves identically.

Gotchas worth knowing first

Middleware can't see response status

It runs before the response is generated, so there's no status code to read. That means no Gaps view: you won't learn that an agent asked for /llms.txt and got a 404. If you're on Vercel, the log drain gets you that for free. Elsewhere, a Cloudflare Worker does.

It must be a secret key, not a publishable one

Agent detection is server-side, so the ingest rejects publishable (pk_) keys for it. A pk_ key in PICKRATE_KEY is the most common cause of an install that looks fine and records nothing — the collector logs a warning to your server console when this happens.

Already composing your own middleware?

Import createMiddleware instead of the default export and call it from inside yours. The one-line form is just a pre-bound convenience.

Questions

Does this slow down my app?

Human requests classify to null with no network call at all, so they cost a string comparison. Agent requests report fire-and-forget, on waitUntil where the runtime supports it.

Does it work on the Edge runtime?

Yes. The collector is dependency-free with no Node built-ins, so it runs in Edge, Node, and Cloudflare's runtime unchanged.

What if I'm not on Vercel?

The middleware works on any host — Railway, Render, Fly, your own server. The log drain is the Vercel-specific option; the middleware isn't.

Other setups

Agent-readable version: https://pickrate.io/install/nextjs.md