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

# Serve Modes

> How Bluesky's serve modes work and how to progress safely from shadow logging to serving verified AI crawlers the optimized artifact.

The Agent Edge Network (AEN) serve mode controls whether a verified AI crawler receives the optimized artifact instead of your normal page. The full model has four modes — `off`, `shadow`, `canary:<pct>`, and `default`. The v0 drop-in Next.js middleware wires the two you need to go live safely: `shadow` (log only) and `default` (serve). Starting in `shadow` means zero risk — you get visibility into crawler activity without changing anything a visitor or crawler sees. When you're confident, you promote to `default`.

## The serve modes

| Mode           | What happens                                                                                                        |
| -------------- | ------------------------------------------------------------------------------------------------------------------- |
| `off`          | Never serve the variant. Every request gets your normal page.                                                       |
| `shadow`       | Every request gets your normal page; the hit is recorded (log only). Zero user impact.                              |
| `canary:<pct>` | A deterministic percentage of URLs are served the variant to verified agents; the rest pass through and are logged. |
| `default`      | Every verified, eligible answer-engine agent whose URL has a generated artifact receives the variant.               |

<Note>
  The v0 drop-in `middleware.ts` implements `shadow` and `default` via the `SERVE_MODE` constant. `off` and `canary:<pct>` also live in the AEN core decision logic (`decide`) and can be stored on a site through the control plane (`upsertConfig`), but no shipped v0 component serves from that stored value yet — the drop-in reads its own `SERVE_MODE` constant, not the site config.
</Note>

<Warning>
  Regardless of serve mode, classic search-index bots — Googlebot, Bingbot, Applebot — **always** receive your normal page. This cloaking firewall runs before serve-mode logic and cannot be overridden. AI Overviews run on the same search index, so branching those crawlers would cloak Search itself.
</Warning>

## Shadow mode — start here

When you first deploy the drop-in middleware, `SERVE_MODE` is set to `"shadow"`:

```ts theme={null}
const SERVE_MODE: "shadow" | "default" = "shadow"; // ← flip to "default" to actually serve
```

In shadow mode, the middleware:

1. Matches the request's user agent against the bot registry.
2. Passes search-index bots straight through (cloaking firewall).
3. Verifies the crawler by checking its source IP against the published vendor CIDR ranges.
4. Sends telemetry for the hit — with the crawler's trust level and purpose — recorded as `PASSTHROUGH`.
5. Always returns `NextResponse.next()`, so every visitor and crawler gets your real page.

It does not fetch or serve the artifact in shadow mode. This lets you confirm detection is working and review hits in Agent Analytics before any AI agent ever receives a variant.

<Tip>
  Leave the middleware in shadow mode for a few days before promoting. You'll build a clear picture of which bots hit which pages and how many are `IP_VERIFIED` versus `UA_ONLY`.
</Tip>

## Default mode — full rollout

When you're satisfied with what you see in Agent Analytics, flip to `default`:

```ts theme={null}
const SERVE_MODE: "shadow" | "default" = "default";
```

In default mode, a crawler receives the optimized variant only when **all** of these hold:

* It is **IP-verified** — its source IP falls inside the bot's published CIDR ranges. (In the AEN core, the higher `SIGNED` tier — Web Bot Auth, RFC 9421 / Ed25519 — also counts as verified; the v0 drop-in verifies by IP only.)
* Its purpose is in the `ENABLED` set.
* A generated artifact exists for the requested URL.

Any request that misses one of these conditions passes through transparently. A missing artifact degrades to passthrough — the middleware never fabricates content.

## Canary rollout

`canary:<pct>` serves the variant to a deterministic slice of URLs. The AEN decision logic hashes the URL and serves only when the hash bucket falls below the configured percentage; every other URL passes through and is logged. This gives a repeatable, gradually-widening ramp — the same URL always lands on the same side of the cutoff.

<Note>
  Canary is implemented in the AEN core decision logic (`decide`) and can be stored on a site via the control plane, but no shipped v0 component serves from it yet. The v0 drop-in `middleware.ts` exposes only `shadow` and `default` through its `SERVE_MODE` constant; to stage a partial rollout with the drop-in, promote to `default` and rely on the naturally limited blast radius (only pages that have a generated artifact can ever be served a variant).
</Note>

## How to change the serve mode

<Steps>
  <Step title="Open middleware.ts">
    Find `middleware.ts` at the root of your Next.js project.
  </Step>

  <Step title="Edit the SERVE_MODE constant">
    Change the value of `SERVE_MODE` near the top of the file:

    ```ts theme={null}
    // Before
    const SERVE_MODE: "shadow" | "default" = "shadow";

    // After (full rollout)
    const SERVE_MODE: "shadow" | "default" = "default";
    ```
  </Step>

  <Step title="Redeploy">
    Push and redeploy. The new mode takes effect on the next request — the drop-in reads its mode from the file, so there is no separate dashboard step.
  </Step>

  <Step title="Confirm in Agent Analytics">
    Watch the served-versus-passthrough breakdown in Agent Analytics. Once you're in `default`, verified crawlers with an available artifact begin showing as `VARIANT` instead of `PASSTHROUGH`.
  </Step>
</Steps>

## Recommended rollout path

```
shadow  →  default (with monitoring)
```

1. **Shadow** — deploy and observe for a few days. Confirm hits are detected and that trust levels and purposes look right.
2. **Default** — once confident, serve verified AI crawlers. Watch Agent Analytics to confirm `VARIANT` responses are flowing.

There is no risk to your search rankings at any stage — Googlebot never receives the variant.

## What `ENABLED` controls

Separately from `SERVE_MODE`, the `ENABLED` set in the drop-in middleware determines which purpose classes are eligible for the variant at all:

```ts theme={null}
const ENABLED = new Set(["USER_TRIGGERED", "RETRIEVAL"]);
```

Both `USER_TRIGGERED` (a person asked an AI to browse your page) and `RETRIEVAL` are enabled by default. Remove a purpose from the set if you only want to serve one class. Requests whose purpose is not in `ENABLED` always pass through, regardless of serve mode. `SEARCH_INDEX` is never eligible — the cloaking firewall handles it first, and the control plane strips it from the enabled purposes defensively.

## Telemetry in every mode

The middleware sends telemetry for every matched, non-search-index AI crawler request — including in `shadow` mode — so Agent Analytics always has data. The `served` field reflects what the crawler actually received:

```ts theme={null}
served: eligible ? (SERVE_MODE === "default" ? served : "PASSTHROUGH") : "PASSTHROUGH"
```

So shadow-mode hits appear in Agent Analytics as `PASSTHROUGH`, giving a true record of what was logged versus what was actually delivered.

For install and edge-token setup, see the [quickstart](/quickstart).
