# Next.js

> next-precog is a route handler plus a provider, for the App Router.

<note>

App Router only. The Pages Router needs a different API route and a different prefetch call,
and is not supported yet.

</note>

## Install

<pm-install name="next-precog">



</pm-install>

```sh [.env]
TYPESAFE_API_KEY="your-api-key"
```

Using a [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) key? Name it
`AI_GATEWAY_API_KEY` and the handler routes through the gateway on its own.

## The route handler

The key stays on the server, which is the whole reason this route exists.

```ts [app/api/precog/route.ts]
import { createPrecogHandler } from "next-precog/server";

export const POST = createPrecogHandler();
```

It validates the body itself, rate limits per caller, caches in process, and answers `503` with
an empty prediction on any failure, with the reason in `x-precog-reason`.

## The provider

```tsx [app/layout.tsx]
import { PrecogProvider, PrecogOverlay } from "next-precog";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <PrecogProvider>
          {children}
          {process.env.NODE_ENV === "development" ? <PrecogOverlay /> : null}
        </PrecogProvider>
      </body>
    </html>
  );
}
```

`PrecogProvider` takes the same options as the Nuxt module, as props:

```tsx
<PrecogProvider
  mode="auto"
  endpoint="/api/precog"
  thresholds={{ prefetch: 0.25, prerender: 0.6 }}
/>
```

## Hand it the prefetching

This is the step that makes a difference, and it has no equivalent config flag.

Next prefetches every `<Link>` that enters the viewport, so a page of thirty links fetches
thirty RSC payloads and there is nothing left to narrow. There is no global switch, so swap the
import:

```tsx
import { PrecogLink as Link } from "next-precog";
```

`PrecogLink` is `next/link` with `prefetch={false}`, which leaves precog to choose and still
lets Next prefetch on hover. Pass `prefetch` explicitly to opt one link back in.

Without this the overlay still works and speculation rules still apply, but the in-app win is
gone: everything was already warm.

## What it warms

`router.prefetch()` for the routes the model picked, which fetches the route's RSC payload and
its chunks. The payload only exists for routes Next renders ahead of time, so a statically
generated section gains the most and a fully dynamic one gains least.

## Reading the state

```tsx
"use client";
import { usePrecog } from "next-precog";

const { enabled, pause, resume, refresh, metrics, plan } = usePrecog();
```

## Not there yet

- No DevTools panel. The Nuxt adapter has one; React DevTools has no equivalent hook for it.
- No published benchmark. [The numbers](/guide/benchmarks) were measured on the Nuxt
playground, and the two effectors are the same, but nobody has run the harness against Next.
Do not assume they transfer exactly.
