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

# Next.js

> Integrate Siteline with Next.js

Use the [`@siteline/nextjs`](https://www.npmjs.com/package/@siteline/nextjs) package to track AI bot visits on your Next.js site. The tracker runs in a fire-and-forget pattern inside Next.js proxy code — requests are not awaited, so there is zero impact on page load times.

## Prerequisites

* A [Siteline website key](/authorization)
* A Next.js project using the [App Router](https://nextjs.org/docs/app) or [Pages Router](https://nextjs.org/docs/pages)

## Setup

<Steps>
  <Step title="Install the package">
    ```bash theme={null}
    npm install @siteline/nextjs
    ```
  </Step>

  <Step title="Add the proxy">
    Create or update your `proxy.ts` file in the root of your project:

    ```typescript proxy.ts theme={null}
    import { withSiteline } from "@siteline/nextjs";

    export default withSiteline({
      websiteKey: process.env.SITELINE_WEBSITE_KEY!,
    });

    export const config = {
      matcher: [
        "/robots.txt",
        "/sitemap.xml",
        "/((?!api|_next/static|_next/image|favicon.ico).*)",
      ],
    };
    ```
  </Step>

  <Step title="Deploy">
    Deploy your application as usual. The proxy will begin tracking AI bot visits immediately.
  </Step>
</Steps>

## How it works

The package hooks into [Next.js proxy](https://nextjs.org/docs/app/api-reference/file-conventions/proxy), which runs on every matched request before the page renders:

1. A visitor (or AI bot) makes a request to your Next.js site
2. The proxy extracts bot-relevant metadata (URL, user agent, IP, referrer)
3. Tracking data is sent to Siteline asynchronously — the request is not awaited
4. The page response is returned to the visitor unmodified

Static assets (`_next/static`, `_next/image`, `favicon.ico`) are excluded via the route matcher.

## Custom Proxy Logic

If you already have proxy logic, pass it as the second argument to `withSiteline`:

```typescript proxy.ts theme={null}
import { type SitelineConfig, withSiteline } from '@siteline/nextjs';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const sitelineConfig: SitelineConfig = {
  websiteKey: process.env.SITELINE_WEBSITE_KEY!,
  debug: process.env.NODE_ENV === 'development',
};

export default withSiteline(sitelineConfig, (request: NextRequest) => {
  const response = NextResponse.next();
  response.headers.set('x-custom-header', 'value');
  return response;
});

export const config = {
  matcher: ['/robots.txt', '/sitemap.xml', '/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
```

## Configuration

<ResponseField name="websiteKey" type="string" required>
  Your Siteline website key. Found under **Agent Analytics** > **Manage Configuration** in your Siteline workspace. You can pass it directly or set it with the `SITELINE_WEBSITE_KEY` environment variable.
</ResponseField>

<ResponseField name="endpoint" type="string">
  Custom Siteline intake endpoint. Most sites can omit this.
</ResponseField>

<ResponseField name="debug" type="boolean">
  Enables debug logging. Use this only while developing or troubleshooting.
</ResponseField>

<ResponseField name="matcher" type="string[]">
  Next.js route matcher config. The example pattern excludes API routes and static assets. Adjust to
  match the routes you want to track.
</ResponseField>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Proxy not tracking visits">
    Ensure `proxy.ts` is in the root of your project (next to `package.json`), not inside `src/` or
    `app/`. Next.js picks up proxy files from the project root.
  </Accordion>

  <Accordion title="Where do I find my website key?">
    Navigate to **Agent Analytics** in your Siteline workspace and click **Manage Configuration** to
    view or regenerate your key.
  </Accordion>

  <Accordion title="I already have proxy logic — will this conflict?">
    No. Pass your existing logic as the second argument to `withSiteline`. It runs asynchronously
    and returns your response unchanged.
  </Accordion>

  <Accordion title="Will this slow down my site?">
    No. The tracking call is fire-and-forget — it is not awaited and never blocks the response. All
    errors are silently caught.
  </Accordion>
</AccordionGroup>

<Tip>
  **Need help?** [Book a setup call](https://cal.com/team/siteline/tech-set-up) and we'll walk you
  through it.
</Tip>
