Next.js Integration
Purpose and Scope
The eve/next integration lets a Next.js application and an eve agent behave like one same-origin project. Instead of deploying a browser frontend separately from an agent service and then coordinating CORS, environment variables, and endpoint URLs, a developer wraps the Next.js configuration with withEve() from eve/next. That wrapper wires public eve routes into the Next.js app during development and deployment, so client code such as useEveAgent() can find the mounted session routes without naming a separate host.
Sources: docs/guides/frontend/nextjs.mdx, packages/eve/src/public/next/index.ts
This page covers the Next.js-specific path: configuring next.config.ts, understanding the local proxy, controlling the eve application root, and using the generated Vercel service wiring. It is intended for developers who already have an eve agent directory and a Next.js app, or who are starting from the Web Chat Next template. It does not replace the broader frontend overview or the eve channel reference; those explain shared client behavior and the canonical HTTP routes that all frontend integrations consume.
Sources: docs/guides/frontend/nextjs.mdx, apps/templates/web-chat-next/README.md
Relevant Source Files
docs/guides/frontend/nextjs.mdx— first-party guide for usingwithEve(), configuringeveRoot, passing hook credentials, and understanding local-versus-deploy topology.apps/frameworks/next/README.md— runnable framework demo notes showing the local command, same-origin rewrites,EVE_BASE_URL, Vercel output behavior, and non-Vercel production environment variables.packages/eve/src/public/next/index.ts— public TypeScript entrypoint foreve/next, including exported constants, public types, and theWithEveOptionscontract.apps/templates/web-chat-next/README.md— template documentation for the generated Web Chat Next app used byeve init --webandeve channels add web.
Basic Configuration
The minimal setup is deliberately small. Install the eve package, make sure your project has an eve agent directory, then import withEve in next.config.ts and export the wrapped config. In the default layout, withEve() expects the eve app root to be the Next.js project root, where an agent/ directory can be discovered. This matches eve’s filesystem-first authoring model: the agent’s instructions, tools, channels, and related files remain ordinary project files while the Next.js app supplies the browser experience.
Sources: docs/guides/frontend/nextjs.mdx
import type { NextConfig } from "next";
import { withEve } from "eve/next";
const nextConfig: NextConfig = {};
export default withEve(nextConfig);If the agent lives outside the Next.js app, pass eveRoot. The option is resolved relative to process.cwd() unless it is absolute, according to the public implementation contract. This is useful in monorepos where a web app and an agent package are siblings, or in a staged migration where a Next.js frontend is mounted over an existing eve application. The important operational rule is that the path should point at the eve application root, not merely at a source subdirectory that happens to contain UI code.
Sources: docs/guides/frontend/nextjs.mdx, packages/eve/src/public/next/index.ts
export default withEve(nextConfig, {
eveRoot: "../my-agent",
});Core Primitives
The first primitive is withEve(), a Next.js config wrapper exported by eve/next. The source types show that it accepts either a Next.js config object or a config function and returns the function-shaped form Next.js can evaluate with the build phase and default config context. This matters when composing integrations: withEve() is meant to sit in the same configuration chain as other Next.js plugins while preserving the application’s existing rewrites and build behavior.
Sources: packages/eve/src/public/next/index.ts
The second primitive is the eve route prefix. The implementation imports EVE_ROUTE_PREFIX and builds proxy rewrite sources from it, while the docs and examples refer to same-origin endpoints such as /eve/v1/session. Those routes are the public HTTP surface that browser clients use to start sessions, send follow-up turns, and stream output. In a Next.js app, the browser talks to the Next.js origin, and withEve() makes sure the request reaches the eve service behind the scenes.
Sources: packages/eve/src/public/next/index.ts, apps/frameworks/next/README.md
The third primitive is the browser hook, usually useEveAgent(). The Next.js guide emphasizes that once withEve() is in place, the hook can be called without a host URL because the routes are mounted same-origin. Cookie-based authentication also benefits from this topology: if Auth.js or another session-cookie system is already active in the web app, the browser naturally sends those cookies on eve requests. For bearer tokens or other non-cookie schemes, the hook can attach headers dynamically.
Sources: docs/guides/frontend/nextjs.mdx
const agent = useEveAgent({
headers: async () => ({
authorization: `Bearer ${await getAccessToken()}`,
}),
});withEve Options Reference
The public WithEveOptions interface documents four optional fields. eveRoot points at the eve application root and defaults to the Next.js app root. eveBuildCommand defaults to eve build and is used for the generated eve Vercel service, so it is the right place for agent-service prework that should not change the Next.js build command. servicePrefix defaults to /_eve_internal/eve, the private namespace used when eve is hosted as a separate experimental Vercel service behind the Next.js app. devServerTimeoutMs controls how long development waits for the eve server to become available.
Sources: docs/guides/frontend/nextjs.mdx, packages/eve/src/public/next/index.ts
| Option | Type | Default | Use when |
|---|---|---|---|
eveRoot | string | Next.js app root | The agent lives outside the web app root. |
eveBuildCommand | string | eve build | The eve service needs custom build prework. |
servicePrefix | string | /_eve_internal/eve | You need a custom private Vercel mount namespace. |
devServerTimeoutMs | number | 180000 | Cold starts are slow or another process is starting eve. |
The implementation adds additional guardrails around these values. eveRoot is normalized with Node path resolution, so relative values become absolute from the current working directory. devServerTimeoutMs must be finite and positive when supplied. The servicePrefix is documented as normalized by adding a leading slash, stripping trailing slashes, and rejecting a value that resolves to the root route. These checks prevent subtle deployment bugs where a private service accidentally becomes mounted at the wrong public path.
Sources: packages/eve/src/public/next/index.ts
Local Development Flow
In local development, running the Next.js dev command starts the web app and lets withEve() manage the agent side. The framework demo says pnpm --filter framework-next dev runs the example, and the Web Chat template uses pnpm --filter web-chat-next-template dev. In both cases, the Next.js config uses withEve() to start an app-local eve agent on a random available port, then rewrites same-origin eve endpoints such as /eve/v1/session to that server. The browser still sees only the Next.js origin.
Sources: apps/frameworks/next/README.md, apps/templates/web-chat-next/README.md
This local proxy behavior is especially important for teams building chat interfaces, dashboards, or authenticated internal tools. Frontend code can be written as if the eve channel belongs to the same app, while the development server keeps process boundaries clear. If an eve server is already running, set EVE_BASE_URL before starting Next.js to reuse it instead of letting withEve() launch another one. That is useful when debugging the agent process separately, sharing a single agent across multiple frontend experiments, or attaching external process tooling.
Sources: apps/frameworks/next/README.md, apps/templates/web-chat-next/README.md
EVE_BASE_URL=http://localhost:3000 pnpm --filter web-chat-next-template devFor slow agent cold starts, increase devServerTimeoutMs. The docs show a value of 300_000, which gives the eve development server up to five minutes to become available. This setting is a local-development reliability knob, not a replacement for fixing an agent that fails to boot. Use it when initialization legitimately takes longer because dependencies are cold, another Next.js process is responsible for starting eve, or a large monorepo is performing first-run compilation.
Sources: docs/guides/frontend/nextjs.mdx, packages/eve/src/public/next/index.ts
Deployment Topology and Vercel Services
On Vercel, withEve() writes generated experimentalServices into .vercel/output/config.json when it detects a linked Vercel project. The documented shape is Next.js at / and eve behind the private /_eve_internal/eve service prefix. Public eve endpoints are then rewritten to that private service, which keeps the eve index route from being exposed at the site root while preserving the same-origin public route contract used by the frontend.
Sources: apps/frameworks/next/README.md, apps/templates/web-chat-next/README.md
The servicePrefix option exists for teams that need to customize that private namespace. If changed, it must match the eve service mount in the Vercel Build Output configuration. Treat the prefix as an internal routing concern, not as the URL that application code should hard-code. Browser code should continue using the public eve route behavior through useEveAgent() or the client API, allowing the integration to rewrite requests differently in development, Vercel production, and other hosting environments.
Sources: docs/guides/frontend/nextjs.mdx, packages/eve/src/public/next/index.ts
For non-Vercel production hosts, the framework demo documents EVE_NEXT_PRODUCTION_ORIGIN. Set it before building the Next.js app to the public origin that serves the eve service namespace. For local production builds, withEve() uses http://127.0.0.1:4274 as the stable eve origin, and EVE_NEXT_PRODUCTION_PORT can choose a different local port before next build and next start. These environment variables are deployment wiring, while withEve() remains the single Next.js integration point.
Sources: apps/frameworks/next/README.md, packages/eve/src/public/next/index.ts
Auth and Route Protection
The Next.js guide calls out an important default: the eve channel is fail-closed. When no agent/channels/eve.ts is authored, eve registers eveChannel({ auth: [vercelOidc(), localDev()] }). That means Vercel OIDC gets the first chance to resolve a Vercel caller, localhost traffic is opened for development, and everything else receives 401. This default is compatible with the same-origin Next.js topology because deployment service-to-service calls can be authenticated while local iteration remains convenient.
Sources: docs/guides/frontend/nextjs.mdx
To use an app-specific policy, author agent/channels/eve.ts and export an eveChannel() configuration. The guide shows importing eveChannel from eve/channels/eve and localDev plus vercelOidc from eve/channels/auth. For a public demo, it mentions none() from eve/channels/auth, which disables authentication. Use that deliberately: same-origin routing removes CORS complexity, but it does not by itself decide who is allowed to start sessions or stream results.
Sources: docs/guides/frontend/nextjs.mdx
import { eveChannel } from "eve/channels/eve";
import { localDev, vercelOidc } from "eve/channels/auth";
export default eveChannel({ auth: [vercelOidc(), localDev()] });Templates, Examples, and Next Steps
The repository includes two practical Next.js entry points. apps/frameworks/next/README.md documents a runnable framework demo for exercising the integration directly. apps/templates/web-chat-next/README.md documents the Web Chat Next template, a small Next.js app that acts as the source for eve’s generated web chat scaffold. The template README explains that it is used by eve init --web and eve channels add web, and that changes should be made in the template app before regenerating the scaffold module.
Sources: apps/frameworks/next/README.md, apps/templates/web-chat-next/README.md
Use the demo when validating framework behavior such as rewrites, environment variables, and Vercel output. Use the template when you want a starting user interface that already knows how to call an app-local eve agent with useEveAgent(). After wiring withEve(), the next pages to read are the frontend overview for hook behavior, the eve channel page for session routes, and auth-and-route-protection for multi-user policy design. If deployment is the immediate goal, review the Vercel service topology before customizing servicePrefix or production origins.
Sources: docs/guides/frontend/nextjs.mdx, apps/templates/web-chat-next/README.md