Bot traffic tracking
Track AI assistants, search engines, and training crawlers that visit your site — the traffic the JavaScript tracker can't see.
Why server-side
The Reignat tracker.js runs in the browser, but bots like ChatGPT, Perplexity, Googlebot, and GPTBot don't execute JavaScript — they just fetch your HTML. To see them you forward each request's User-Agent to Reignat from your server. Reignat classifies it and records the crawl if it's a known bot.
Next.js middleware
Add a middleware.ts at your project root. It runs on every request and reports the User-Agent without blocking the response.
// middleware.tsimport { NextResponse, type NextRequest } from "next/server" export function middleware(req: NextRequest) { // Fire-and-forget; never block the response. fetch("https://www.reignat.com/api/track/bot", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ projectId: "your-project-id", path: req.nextUrl.pathname, userAgent: req.headers.get("user-agent") ?? "", ip: req.headers.get("x-forwarded-for") ?? "", }), }).catch(() => {}) return NextResponse.next()} // Skip static assets so you only report real page requests.export const config = { matcher: ["/((?!_next/|favicon.ico|.*\\..*).*)"],}// middleware.tsimport { NextResponse, type NextRequest } from "next/server" export function middleware(req: NextRequest) { // Fire-and-forget; never block the response. fetch("https://www.reignat.com/api/track/bot", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ projectId: "your-project-id", path: req.nextUrl.pathname, userAgent: req.headers.get("user-agent") ?? "", ip: req.headers.get("x-forwarded-for") ?? "", }), }).catch(() => {}) return NextResponse.next()} // Skip static assets so you only report real page requests.export const config = { matcher: ["/((?!_next/|favicon.ico|.*\\..*).*)"],}Node / any backend
Any server can report a hit with a single POST. Express example:
app.use((req, res, next) => { fetch("https://www.reignat.com/api/track/bot", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ projectId: "your-project-id", path: req.path, userAgent: req.headers["user-agent"] || "", ip: req.headers["x-forwarded-for"] || req.socket.remoteAddress || "", }), }).catch(() => {}) next()})app.use((req, res, next) => { fetch("https://www.reignat.com/api/track/bot", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ projectId: "your-project-id", path: req.path, userAgent: req.headers["user-agent"] || "", ip: req.headers["x-forwarded-for"] || req.socket.remoteAddress || "", }), }).catch(() => {}) next()})Payload
POST https://www.reignat.com/api/track/bot with a JSON body:
projectIdstring (required)
Your project ID (the tracker data-site value).
userAgentstring (required)
The incoming request's User-Agent header.
pathstring
The requested path, e.g. /pricing. Defaults to /.
ipstring
The client IP (for bot geography). Optional.
What gets detected
Recognised bots are grouped into three categories:
AI answerscategory
Assistants fetching live to answer a prompt: ChatGPT, Claude, Perplexity, Gemini, Copilot.
Indexingcategory
Search-engine crawlers: Googlebot, Bingbot, DuckDuckBot, YandexBot, Baiduspider, Applebot.
Trainingcategory
Model-training scrapers: GPTBot, ClaudeBot, Google-Extended, CCBot, Bytespider, Amazonbot.
tracker.js as usual.