https://github.com/apideck-libraries/agent-analytics-nextjs-starter
Next.js 15 starter that tracks AI agent traffic (ClaudeBot, GPTBot, Perplexity, and 20+ more) in PostHog. One-click deploy, sample Markdown-mirror docs routes, @apideck/agent-analytics wired in.
https://github.com/apideck-libraries/agent-analytics-nextjs-starter
Last synced: 3 months ago
JSON representation
Next.js 15 starter that tracks AI agent traffic (ClaudeBot, GPTBot, Perplexity, and 20+ more) in PostHog. One-click deploy, sample Markdown-mirror docs routes, @apideck/agent-analytics wired in.
- Host: GitHub
- URL: https://github.com/apideck-libraries/agent-analytics-nextjs-starter
- Owner: apideck-libraries
- License: mit
- Created: 2026-04-19T07:23:20.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-19T08:46:28.000Z (3 months ago)
- Last Synced: 2026-04-19T09:29:22.383Z (3 months ago)
- Language: TypeScript
- Homepage: https://agent-analytics-nextjs-starter.vercel.app
- Size: 22.5 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
---
name: Agent Analytics Starter
slug: agent-analytics-starter
description: Track AI agent traffic (ClaudeBot, GPTBot, Perplexity, and 20+ more) in PostHog via middleware. Serves clean Markdown to agents on the same URLs — @apideck/agent-analytics wired in.
framework: Next.js
useCase: Edge Middleware
css: Plain CSS
deployUrl: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fapideck-libraries%2Fagent-analytics-nextjs-starter&env=NEXT_PUBLIC_POSTHOG_KEY,NEXT_PUBLIC_POSTHOG_HOST&envDescription=PostHog%20project%20API%20key%20and%20host&envLink=https%3A%2F%2Fgithub.com%2Fapideck-libraries%2Fagent-analytics-nextjs-starter%23environment-variables&project-name=agent-analytics-starter&repository-name=agent-analytics-starter
demoUrl: https://agent-analytics-nextjs-starter.vercel.app
relatedTemplates:
- bot-protection-datadome
- bot-protection-botd
---

# Agent Analytics — Next.js starter
### Next.js 15 starter that tracks AI agent traffic in PostHog — drop in your API key, deploy, watch ClaudeBot show up in your dashboard.
**One-click deploy.** Sample `/docs/` routes that serve as HTML to browsers and **clean Markdown to AI agents**. Every Markdown fetch fires a `doc_view` event with `is_ai_bot`, `source`, and `user_agent` — ready to segment in PostHog.
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fapideck-libraries%2Fagent-analytics-nextjs-starter&env=NEXT_PUBLIC_POSTHOG_KEY,NEXT_PUBLIC_POSTHOG_HOST&envDescription=PostHog%20project%20API%20key%20and%20host&envLink=https%3A%2F%2Fgithub.com%2Fapideck-libraries%2Fagent-analytics-nextjs-starter%23environment-variables&project-name=agent-analytics-starter&repository-name=agent-analytics-starter)
[**Live demo**](https://agent-analytics-nextjs-starter.vercel.app) · [**@apideck/agent-analytics**](https://github.com/apideck-libraries/agent-analytics) · [**The pattern, explained**](https://addyosmani.com/blog/agentic-engine-optimization/)
---
## What this template does
AI crawlers don't run JavaScript — so your client-side analytics never see them. This template closes that gap:
1. **`middleware.ts`** uses [`@apideck/agent-analytics`](https://www.npmjs.com/package/@apideck/agent-analytics) to detect 20+ known AI bots (ClaudeBot, GPTBot, PerplexityBot, Google-Extended, Applebot-Extended, Bytespider, Cursor, Windsurf, and more) and capture a `doc_view` event in PostHog on every request.
2. **`/docs/` routes** are served as clean Markdown when an agent asks (via `.md` suffix, `Accept: text/markdown`, or a known bot UA) — otherwise HTML. Same URL, two representations.
3. **Every Markdown response** carries `Content-Signal`, `Vary: accept`, and `x-markdown-tokens` headers so agents can budget context before parsing.
Runs on Vercel's Fluid Compute. Zero infrastructure to manage, events land in PostHog seconds after deploy.
## Quick start
### 1. Deploy
Click the Deploy button above, or:
```bash
npx create-next-app --example https://github.com/apideck-libraries/agent-analytics-nextjs-starter my-app
cd my-app
vercel --prod
```
### 2. Set env vars
In the Vercel deploy prompt (or your project's env settings):
| Variable | Required | Example |
|---|---|---|
| `NEXT_PUBLIC_POSTHOG_KEY` | yes | `phc_xxxxxxxx` — from PostHog project settings |
| `NEXT_PUBLIC_POSTHOG_HOST` | no (defaults to US cloud) | `https://us.i.posthog.com`, `https://eu.i.posthog.com`, or your own reverse-proxy |
If `NEXT_PUBLIC_POSTHOG_KEY` is absent the middleware silently no-ops — nothing breaks, events just don't flow.
### 3. Verify
```bash
# From your local terminal, pointed at the deployment:
curl -A "ClaudeBot/1.0 probe-$(date +%s)" https://.vercel.app/docs/intro
```
Open PostHog → Activity and filter events by `event = doc_view`. You should see one event with `is_ai_bot: true`, `source: ua-rewrite`, and the probe UA you sent.
---
## How it works
```
Agent / Browser middleware.ts PostHog
──────────────── ──────────────────────────────────────── ──────────
│ │
│ GET /docs/intro │
│ Accept: text/markdown (or .md suffix, or AI-bot UA) │
├──────────────────────┐ │
│ ▼ │
│ markdownServeDecision(req) → reason │
│ │ │
│ ┌────────────────┴───────────────┐ │
│ ▼ ▼ │
│ trackDocView(req, { NextResponse.rewrite( │
│ analytics, req.nextUrl → /md/... │
│ source: reason, ) │
│ properties: {...} │
│ }) ────fire-and-forget──────keepalive fetch──►───────────► │
│ │
│ ◄──── 200 text/markdown ──────────────── │
│ Content-Signal, x-markdown-tokens │
│ │
```
Key properties:
- **Fire-and-forget** — the capture is non-blocking. `keepalive: true` lets it survive after the response returns.
- **No person profiles** — `$process_person_profile: false` tells PostHog not to create one per unique bot fingerprint.
- **Stable anon distinct_id** — djb2 hash of `ip:ua` collapses repeat fetches from the same agent into one visitor.
## Structure
```
.
├── middleware.ts # The star of the show
├── app/
│ ├── layout.tsx
│ ├── page.tsx # Landing page with probe instructions
│ ├── globals.css
│ └── docs/[slug]/page.tsx # Human-facing docs (HTML)
├── public/
│ ├── md/docs/
│ │ ├── intro.md # Agent-facing Markdown mirror
│ │ └── usage.md
│ └── llms.txt # Agent-friendly site index
├── .env.example
├── package.json
└── README.md
```
## Customising
**Add a new `/docs/` page**:
1. Create `public/md/docs/.md` — what agents see.
2. Add an entry to the `DOCS` object in `app/docs/[slug]/page.tsx` — what browsers see.
3. Update `public/llms.txt` so agents can discover it.
**Extend the mirror to cover other routes** (e.g. `/blog/*`, `/guides/*`):
Edit `resolveMirrorPath` in `middleware.ts`:
```ts
function resolveMirrorPath(pathname: string): string | null {
if (pathname.startsWith('/docs/')) return `/md${pathname}.md`
if (pathname.startsWith('/blog/')) return `/md${pathname}.md` // ← add this
return null
}
```
Then create matching `public/md/blog/*.md` files.
**Swap analytics backends** — replace the PostHog adapter with a webhook, Mixpanel, or your own callback:
```ts
import { trackDocView, webhookAnalytics } from '@apideck/agent-analytics'
const analytics = webhookAnalytics({
url: 'https://collector.example.com/events',
headers: { Authorization: `Bearer ${process.env.COLLECTOR_TOKEN}` }
})
```
Any `{ capture(event) }` object is a valid adapter.
## Environment variables
| Variable | Description |
|---|---|
| `NEXT_PUBLIC_POSTHOG_KEY` | PostHog project API key (the public key used by the JS SDK). Find it under *Project settings → Project API Key*. |
| `NEXT_PUBLIC_POSTHOG_HOST` | PostHog ingestion host. Defaults to `https://us.i.posthog.com`. Set to `https://eu.i.posthog.com` for EU cloud, or your own reverse-proxy domain (e.g. `https://svc.example.com`) to dodge ad-blockers. |
## Learn more
- [`@apideck/agent-analytics` on GitHub](https://github.com/apideck-libraries/agent-analytics) — the library powering this template
- [Agentic Engine Optimization](https://addyosmani.com/blog/agentic-engine-optimization/) — the case for agent-ready docs sites
- [contentsignals.org](https://contentsignals.org) — the `Content-Signal` header spec
- [developers.apideck.com](https://developers.apideck.com) — the production docs site this pattern was extracted from
## License
MIT © Apideck