agent tracking middleware.md

Detect AI agent visits with agent tracking middleware

Install Lightsage's lightweight middleware on Next.js, Vercel, Cloudflare, Express, Astro, or Netlify to detect coding agent visits to your docs in real time.

When a coding agent reads your documentation, it leaves no trace in a standard analytics tool. Google Analytics records human sessions. Your CDN logs record IP addresses. Neither tells you that Claude Code spent the last hour reading your authentication reference — or that Cursor crawled your quick start but never reached your error handling guide.

Lightsage's agent tracking middleware sits in front of your application and identifies AI agent traffic by user agent signature. It adds zero latency to user-facing requests and sends agent visit events to your Lightsage dashboard in real time. The following agents are detected:

Getting your API key

Find your LIGHTSAGE_API_KEY in your Lightsage account settings. Store it as an environment variable — never commit it to source control.

Installation

// Next.js (middleware.ts)
theme={null}
// middleware.ts — place this in your project root
import { withAgentTracking } from '@lightsage/agent-tracker/next';

export default withAgentTracking({
  apiKey: process.env.LIGHTSAGE_API_KEY,
});

export const config = {
  matcher: ['/((?!api|_next|admin).*)'],
};
// Vercel (middleware.ts)
theme={null}
// Vercel uses the same Next.js middleware format.
// Place middleware.ts in your project root.
import { withAgentTracking } from '@lightsage/agent-tracker/next';

export default withAgentTracking({
  apiKey: process.env.LIGHTSAGE_API_KEY,
});

export const config = {
  // Exclude Vercel internals and your API routes
  matcher: ['/((?!api|_next|_vercel|admin).*)'],
};
// Cloudflare Workers
theme={null}
// worker.ts
import { createAgentTracker } from '@lightsage/agent-tracker/cloudflare';

const tracker = createAgentTracker({
  apiKey: env.LIGHTSAGE_API_KEY,
});

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // Track the request before forwarding
    await tracker.track(request);

// Continue with your normal handler
    return fetch(request);
  },
};
// Express.js
theme={null}
// app.ts
import express from 'express';
import { agentTrackingMiddleware } from '@lightsage/agent-tracker/express';

const app = express();

// Add before your route handlers
app.use(
  agentTrackingMiddleware({
    apiKey: process.env.LIGHTSAGE_API_KEY,
    // Optional: exclude paths you don't want tracked
    exclude: ['/api', '/admin', '/health'],
  })
);

app.get('/', (req, res) => {
  res.send('Hello world');
});

app.listen(3000);
// Netlify Edge Functions
theme={null}
// netlify/edge-functions/agent-tracking.ts
import { trackAgentRequest } from '@lightsage/agent-tracker/netlify';

export default async (request: Request) => {
  await trackAgentRequest(request, {
    apiKey: Deno.env.get('LIGHTSAGE_API_KEY'),
  });

// Return undefined to continue to the next handler
  return;
};

export const config = {
  path: '/*',
  excludedPath: ['/api/*', '/admin/*'],
};

Installing the package

npm

theme={null}
npm install @lightsage/agent-tracker

pnpm

theme={null}
pnpm add @lightsage/agent-tracker

yarn

theme={null}
yarn add @lightsage/agent-tracker

The matcher config

For Next.js and Vercel, the matcher config controls which routes the middleware runs on. The pattern /((?!api|_next|admin).*) means: run on all routes except those starting with api/, _next/, or admin/.

You should exclude:

If you have additional paths to exclude — for example, a staging environment path or internal health check endpoint — add them to the exclusion list:

theme={null}
export const config = {
  matcher: ['/((?!api|_next|admin|staging|health).*)'],
};

What you see in the dashboard

Once the middleware is deployed and agents begin visiting your site, the Lightsage dashboard shows:

The first agent visits may appear in your dashboard within minutes of deploying the middleware, depending on how actively the agents currently crawl your domain. If you see no visits within 48 hours, verify that your robots.txt is not blocking AI crawlers. See Optimize your API for AI coding agent discovery for the robots.txt configuration.

Performance impact

The middleware runs on your edge infrastructure and uses a fire-and-forget pattern for the tracking event — it does not add latency to the response path for any visitor, human or agent. The identification logic is a user-agent string lookup, which completes in microseconds.

For Cloudflare Workers and Netlify Edge Functions, use event.waitUntil() or the equivalent platform primitive to ensure the tracking event completes even after the response is returned, without blocking the response itself.

Next steps

Agent visit tracking gives you the web-crawl half of the picture. To track what agents recommend when developers ask implementation questions, see How to track coding agent recommendations for your API.

To connect recognized AI acquisition sources to sign-up, demo, checkout, and activation events, see Measure agent-attributed growth.

To improve the quality of what agents find when they visit your docs, see Optimize your API for AI coding agent discovery.