# Next.js

> Set up the inference shell proxy in Next.js with App Router or Page Router.

**URL:** https://inference.sh/docs/api/sdk/proxy/nextjs
**Last updated:** 2026-10-11

---

Set up the inference shell proxy in Next.js with App Router or Page Router.

---

## Installation

```bash
npm install @inferencesh/sdk
```

---

## App Router (Recommended)

Create `app/api/inference/proxy/route.ts`:

```typescript
import { createHandler } from "@inferencesh/sdk/proxy/nextjs";

export const { GET, POST } = createHandler({
  allowedEndpoints: ["my-team/*"],
});
```

The proxy forwards app runs and agent chats only; `allowedEndpoints` limits them to your apps and agents. See [options](/docs/api/sdk/server-proxy#options).

> [!WARNING]
> Anyone who can reach the proxy route runs apps and agents on your API key. In production set `allowedEndpoints` and `isAuthenticated` (see [what the proxy forwards](/docs/api/sdk/server-proxy#what-the-proxy-forwards)), and create a **Run only** key in a workspace that holds nothing else.

### With Edge Runtime

```typescript
import { createHandler } from "@inferencesh/sdk/proxy/nextjs";

export const runtime = "edge";
export const { GET, POST } = createHandler({ allowedEndpoints: ["my-team/*"] });
```

---

## Page Router

Create `pages/api/inference/proxy.ts`:

```typescript
import { createPageHandler } from "@inferencesh/sdk/proxy/nextjs";

export default createPageHandler({ allowedEndpoints: ["my-team/*"] });
```

> **Note**: Page Router doesn't support streaming. Use App Router for real-time updates.

---

## Environment Variable

Add your API key to `.env.local`:

```bash
INFERENCE_API_KEY="inf_your_key_here"
```

---

## Client Configuration

```typescript
"use client";

import { inference } from "@inferencesh/sdk";

const client = inference({
  proxyUrl: "/api/inference/proxy"
});

export async function generateImage(prompt: string) {
  const result = await client.run({
    app: "infsh/flux",
    input: { prompt }
  });
  
  return result.output;
}
```

---

## Authentication

`isAuthenticated` gets the `NextRequest`; `false` answers `401`:

```typescript
// app/api/inference/proxy/route.ts
import { createHandler } from "@inferencesh/sdk/proxy/nextjs";
import { getSession } from "@/lib/auth";

export const { GET, POST } = createHandler({
  allowedEndpoints: ["my-team/*"],
  isAuthenticated: async (req) => Boolean(await getSession(req)),
});
```

---

## CORS (Cross-Origin)

If calling from a different domain:

```typescript
import { createHandler } from "@inferencesh/sdk/proxy/nextjs";
import { NextResponse } from "next/server";

export async function OPTIONS() {
  return new NextResponse(null, {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
      "Access-Control-Allow-Headers": "Content-Type, x-inf-target-url",
    },
  });
}

export const { GET, POST } = createHandler({ allowedEndpoints: ["my-team/*"] });
```

---

## Vercel Deployment

See [Vercel](/docs/api/sdk/vercel) for deployment-specific configuration and timeout settings.
