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

# Next.js

> Integrate Polpo agents into Next.js applications with server-side security.

Next.js is the recommended framework for building production Polpo apps. Use Server Components for secure API calls and Client Components for real-time UI.

## Install

```bash theme={null}
npm install @polpo-ai/sdk @polpo-ai/react
```

## Environment variables

```bash theme={null}
# .env.local
POLPO_URL=https://{project}.polpo.cloud       # server-side only
POLPO_API_KEY=sk_live_...                      # server-side only
```

<Warning>
  Keep `POLPO_API_KEY` server-side only (no `NEXT_PUBLIC_` prefix). Use a route handler to proxy authenticated requests.
</Warning>

## Server-side: Route Handler

Create an API route that proxies chat completions with the API key injected server-side:

```typescript theme={null}
// app/api/chat/route.ts
import { PolpoClient } from "@polpo-ai/sdk";

const client = new PolpoClient({
  baseUrl: process.env.POLPO_URL!,
  apiKey: process.env.POLPO_API_KEY!,
});

export async function POST(req: Request) {
  const { messages, agent } = await req.json();

  const stream = client.chatCompletionsStream({ agent, messages });

  return new Response(
    new ReadableStream({
      async start(controller) {
        for await (const chunk of stream) {
          controller.enqueue(
            new TextEncoder().encode(`data: ${JSON.stringify(chunk)}\n\n`)
          );
        }
        controller.enqueue(new TextEncoder().encode("data: [DONE]\n\n"));
        controller.close();
      },
    }),
    {
      headers: {
        "Content-Type": "text/event-stream",
        "Cache-Control": "no-cache",
      },
    }
  );
}
```

## Server-side: Server Components

Fetch agent data directly in Server Components — no client-side API key exposure:

```tsx theme={null}
// app/agents/page.tsx
import { PolpoClient } from "@polpo-ai/sdk";

const client = new PolpoClient({
  baseUrl: process.env.POLPO_URL!,
  apiKey: process.env.POLPO_API_KEY!,
});

export default async function AgentsPage() {
  const agents = await client.getAgents();

  return (
    <div>
      <h1>Agents</h1>
      {agents.map(a => (
        <div key={a.name}>
          <h2>{a.name}</h2>
          <p>{a.role}</p>
        </div>
      ))}
    </div>
  );
}
```

## Client-side hooks through a proxy

Point `PolpoProvider` at an application-owned proxy. Do not pass the project URL or key through a Server Component: serialized props are still visible to the browser. The proxy must inject `POLPO_API_KEY` and forward `/v1` resource routes.

```tsx theme={null}
// app/dashboard/layout.tsx (Server Component)
import { DashboardShell } from "./shell";

export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  return <DashboardShell>{children}</DashboardShell>;
}
```

```tsx theme={null}
// app/dashboard/shell.tsx (Client Component)
"use client";

import { PolpoProvider } from "@polpo-ai/react";

export function DashboardShell({ children }: { children: React.ReactNode }) {
  return (
    <PolpoProvider baseUrl="/api/polpo" autoConnect={false}>
      {children}
    </PolpoProvider>
  );
}
```

Native browser `EventSource` cannot add the Cloud authorization header. Implement `/api/events` as an authenticated SSE proxy before enabling `autoConnect`.

```tsx theme={null}
// app/dashboard/page.tsx (Client Component)
"use client";

import { useTasks } from "@polpo-ai/react";

export default function DashboardPage() {
  const { tasks, isLoading } = useTasks();

  if (isLoading) return <p>Loading tasks...</p>;

  return (
    <ul>
      {tasks.map(t => <li key={t.id}>{t.title} — {t.status}</li>)}
    </ul>
  );
}
```

## Pattern: Secure chat proxy

The recommended pattern for production chat apps:

```
Browser (Client Component)
    │
    ├── POST /api/chat (your Next.js route)
    │       │
    │       └── PolpoClient.chatCompletionsStream()
    │               │ (POLPO_API_KEY injected server-side)
    │               │
    │               └── Polpo API
    │
    └── SSE /api/events (optional, for live task updates)
```

This keeps the API key server-side while streaming responses to the browser.

## Templates

Get started faster with pre-built templates. Browse all available templates at [ui.polpo.sh/examples](https://ui.polpo.sh/examples) — these are also available in the `polpo create` wizard.
