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

# Next.js

> Track AI crawlers on Next.js with the beacon SDK.

<Steps>
  <Step title="Install">
    ```bash theme={null}
    npm install @snowseo/beacon
    ```
  </Step>

  <Step title="Set your site key">
    ```bash .env theme={null}
    SNOWSEO_BEACON_KEY=sb_live_...
    ```

    <Warning>
      Never prefix it with `NEXT_PUBLIC_`. That inlines the value into the browser bundle, publishing a key that authorises writes for your whole site.
    </Warning>
  </Step>

  <Step title="Create the beacon">
    ```ts beacon.ts theme={null}
    import { createBeacon } from "@snowseo/beacon";

    export const beacon = createBeacon({
      siteUrl: "https://example.com",
      analytics: { key: process.env.SNOWSEO_BEACON_KEY! },
    });
    ```

    `siteUrl` decides which hostname hits are attributed to, so a wrong value mis-files everything.
  </Step>

  <Step title="Wire it into your proxy">
    ```ts proxy.ts theme={null}
    // middleware.ts before Next 16
    import { beaconMiddleware, beaconAdvertise } from "@snowseo/beacon/next";
    import { NextResponse } from "next/server";
    import { beacon } from "./beacon";

    export default async function proxy(request, event) {
      const markdown = await beaconMiddleware(beacon, request, event);
      if (markdown) return markdown;

      return beaconAdvertise(beacon, request, NextResponse.next(), event);
    }
    ```
  </Step>
</Steps>

Verify:

```bash theme={null}
curl -A "GPTBot/1.2" https://example.com/
```

***

## A note on `Vary`

Next rewrites `Vary` on every document response for its own RSC cache, which drops the `Vary: Accept` the middleware adds. Markdown responses keep it, so Next's own cache is fine.

A shared CDN in front of Next could still serve a cached HTML page to a client that asked for Markdown. Either add `Accept` to the CDN's cache key, or rely on the `.md` URLs, which are distinct URLs and need no `Vary` at all.

***

## Static pages and CDN caching

Anything served from Vercel's CDN without invoking your proxy is invisible, the same way a page cache is on any platform. Requests that reach your middleware are counted in full.
