> ## Documentation Index
> Fetch the complete documentation index at: https://www.usenotra.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Track AI crawlers on React Router

> Install the @usenotra/geo tracker in a React Router app to log AI crawlers, AI-cited fetches and AI referrals in Notra.

This guide adds the Notra tracker to a React Router app in framework mode in about five minutes, and you only touch one file, `app/root.tsx`.

> [!TIP]
>
> The Traffic page has a **Copy agent prompt** button. Paste the prompt into Claude Code, Cursor or Codex and the agent runs these steps for you.

**1. Get your token**

Open **Traffic** in the GEO sidebar. Until the first event arrives the page shows **No activity yet** with the full install panel: **Install the package**, **Set your token** and **Add the proxy**. The token appears in the **Set your token** section, and the **Copy agent prompt** button copies an instruction block you can paste into a coding agent.

From the API, reading the snippets needs `traffic.read` and issuing the token needs `traffic.write`:

```bash theme={"system"}
curl https://api.usenotra.com/v1/geo/ingest/setup \
  -H "Authorization: Bearer $NOTRA_API_KEY"
```

```bash theme={"system"}
curl -X POST "https://api.usenotra.com/v1/geo/ingest/token?projectId=$PROJECT_ID" \
  -H "Authorization: Bearer $NOTRA_API_KEY"
```

Both return `ingestUrl`, `snippet` (the Next.js snippet) and `snippets` with `next`, `nuxt`, `tanstack`, `astro`, `sveltekit`, `reactRouter` and `netlify` keys. The token endpoint also returns `token`. The ingest routes are organization-level, so pass `projectId` to bind the token to one project or omit it to track the whole organization. Issuing a token doesn't invalidate tokens issued earlier.

Install the same project token on every domain the project tracks, and add extra hostnames under **Tracked domains** in GEO settings.

**2. Install the package**

```bash npm theme={"system"}
npm install @usenotra/geo
```

```bash yarn theme={"system"}
yarn add @usenotra/geo
```

```bash pnpm theme={"system"}
pnpm add @usenotra/geo
```

```bash bun theme={"system"}
bun add @usenotra/geo
```

The package has zero dependencies and no Node APIs in the core, so it runs on edge runtimes. You can also install it with npm, pnpm or yarn.

**3. Set the environment variable**

Add the token as `NOTRA_GEO_TOKEN` in your site's environment variables, both locally and at your hosting provider, and never hardcode or commit it.

**4. Add the tracker**

```tsx app/root.tsx theme={"system"}
import { createGeoMiddleware } from "@usenotra/geo/react-router";
import type { Route } from "./+types/root";

const geo = createGeoMiddleware({
  token: process.env.NOTRA_GEO_TOKEN!,
  endpoint: "https://ingest.usenotra.com",
});

export const middleware: Route.MiddlewareFunction[] = [geo];
```

Root middleware runs on every server request. The tracker sends the event after your loaders and render have produced the response, so the visitor never waits for it, and it passes the response and errors through unchanged. If `app/root.tsx` already exports `middleware`, add `geo` to that array.

React Router 8 always runs middleware. On React Router 7, upgrade to 7.9 or later and turn middleware on:

```typescript react-router.config.ts theme={"system"}
import type { Config } from "@react-router/dev/config";

export default {
  future: { v8_middleware: true },
} satisfies Config;
```

**5. Keep the send alive on serverless hosts**

Long-running Node servers such as `react-router-serve` or Express need nothing extra. Serverless hosts can stop the function once the response is sent, so pass your host's `waitUntil` to let the send finish:

```tsx Vercel theme={"system"}
import { waitUntil } from "@vercel/functions";

const geo = createGeoMiddleware({
  token: process.env.NOTRA_GEO_TOKEN!,
  endpoint: "https://ingest.usenotra.com",
  waitUntil,
});
```

```tsx Cloudflare Workers theme={"system"}
import { waitUntil } from "cloudflare:workers";

const geo = createGeoMiddleware({
  token: process.env.NOTRA_GEO_TOKEN!,
  endpoint: "https://ingest.usenotra.com",
  waitUntil,
});
```

On Vercel, install `@vercel/functions` first.

**6. Deploy and verify**

After you deploy your site, the Traffic page switches from the install panel to the dashboard once Notra stores the first AI crawler visit or referral. Crawlers visit on their own schedule, so the first event can take a while on a quiet site.

## Next steps

> **[Tracker reference](/docs/ai-traffic/tracker-reference)**
>
> Options, excluded paths, privacy and token rotation.

> **[Journey tagging](/docs/ai-traffic/journeys)**
>
> Follow one agent across the pages it reads.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.