Nuxt, SvelteKit, Vue, and Svelte

Purpose and Scope

This page explains how eve frontend integrations let a browser application and an eve agent run as one project instead of as separately configured services. The main repository-backed example is Nuxt through the eve/nuxt module, and the same product model extends to SvelteKit through eve/sveltekit, Vue through eve/vue, and Svelte through eve/svelte. The reader problem is practical: you want a framework app to send turns to an agent, receive streamed output, and deploy without managing CORS, public agent URLs, or a second web origin by hand.

The core idea is same-origin mounting. In local development, the frontend dev server is the browser-facing origin, while eve runs next to it and the integration proxies eve routes through the framework server. On Vercel, a single project carries both the web app and the eve runtime, with the public app in front of the runtime. That means frontend code can call the agent binding without knowing where the backend agent is physically running. Sources: docs/guides/frontend/nuxt.mdx

This page is not a complete replacement for each composable or hook API reference. Instead, it orients application developers to the common topology, the framework-specific registration points, the default auth behavior for the embedded eve channel, and the small set of options that control where the agent directory lives and how it is built. After reading it, you should know which integration entry point to add to your app and which deeper page to read next.

Relevant Source Files

  • docs/guides/frontend/nuxt.mdx — Defines the Nuxt frontend guide, including eve/nuxt registration, eveRoot, eveBuildCommand, useEveAgent usage, default Eve channel authentication, local development proxying, Vercel deployment topology, and non-Vercel production environment variables.

Core Primitives

An eve frontend integration has four important primitives. The first is the agent directory, usually agent/, which contains the filesystem-first backend agent authored with instructions, tools, channels, and related capabilities. The second is the framework integration, such as the Nuxt module or the SvelteKit Vite plugin, which mounts that agent into the frontend project. The third is the client binding, such as useEveAgent, which opens or resumes a session, sends user turns, and exposes status and streamed state to components. The fourth is the Eve channel, the HTTP-facing channel that receives browser traffic for session and turn endpoints. Sources: docs/guides/frontend/nuxt.mdx

The Nuxt guide makes the coupling between these primitives explicit. Registering eve/nuxt is enough for the module to look for an agent/ folder in the Nuxt project root, start the eve runtime during local development, and proxy the mounted routes through the Nuxt origin. Because the Vue composable discovers the mounted routes, component code does not need to pass an agent host or duplicate the deployment URL in environment variables. That is the key difference from a hand-rolled two-service setup where frontend and backend URLs drift independently. Sources: docs/guides/frontend/nuxt.mdx

Framework Registration

For Nuxt, add the module to nuxt.config.ts. This is the smallest same-project configuration and assumes the agent directory is located at agent/ in the Nuxt project root. The supplied Nuxt guide frames this as a single dev server and single Vercel deploy experience, where the module owns route mounting and proxy setup for the browser-facing app. Sources: docs/guides/frontend/nuxt.mdx

nuxt.config.ts
export default defineNuxtConfig({
  modules: ["eve/nuxt"],
});

When the agent lives outside the Nuxt root, configure eveRoot. This is useful in monorepos or migration projects where a frontend app and an existing eve agent are siblings rather than one being nested inside the other. The Nuxt integration intentionally exposes only a small options surface so the topology remains predictable: point the module at the agent root, and optionally tell it how to build that agent for deployment. Sources: docs/guides/frontend/nuxt.mdx

export default defineNuxtConfig({
  modules: ["eve/nuxt"],
  eve: {
    eveRoot: "../my-agent",
  },
});

For SvelteKit, the official integration follows the same pattern through a Vite plugin rather than a Nuxt module. Add eveSvelteKit() before sveltekit() so the eve integration participates in Vite setup before the SvelteKit adapter/plugin finalizes the app pipeline. Like Nuxt, the plugin looks for an agent/ folder by default and accepts eveRoot when the agent lives elsewhere. The component-level API is Svelte-oriented, but the deployment goal remains the same: keep the app and agent on one origin.

vite.config.ts
import { sveltekit } from "@sveltejs/kit/vite";
import { eveSvelteKit } from "eve/sveltekit";
import { defineConfig } from "vite";
 
export default defineConfig({
  plugins: [eveSvelteKit(), sveltekit()],
});

Calling the Client Binding

In Nuxt, useEveAgent from eve/vue is auto-imported by the module, so a component can call it directly. The returned status value lets the UI distinguish idle, submitted, streaming, and error states, while send posts a user turn to the current session. The guide’s example also shows a practical UI guard: treat both submitted and streaming as busy states so a form cannot double-submit while the current turn is in flight. Sources: docs/guides/frontend/nuxt.mdx

<script setup lang="ts">
const { status, send } = useEveAgent();
 
const isBusy = computed(() => status.value === "submitted" || status.value === "streaming");
 
const message = ref("");
 
async function handleSubmit() {
  const text = message.value.trim();
  if (!text || isBusy.value) return;
  message.value = "";
  await send({ message: text });
}
</script>

In plain Vue, import useEveAgent from eve/vue instead of relying on Nuxt auto-imports. In Svelte, import useEveAgent from eve/svelte; the Svelte binding exposes an agent object whose status and send members serve the same role. Across both component models, the important concept is the session: a long-lived conversation state that accumulates messages and streamed events. The binding hides transport details so the component can focus on rendering messages, disabling controls while work is active, stopping a request, or resetting a session.

Authentication and Route Protection

The embedded Eve channel is not open by default. The Nuxt guide states that when no agent/channels/eve.ts file is authored, eve registers eveChannel({ auth: [vercelOidc(), localDev()] }). In that default policy, vercelOidc() gets the first chance to resolve a Vercel caller, localDev() permits remaining localhost requests, and all other callers receive 401. This fail-closed behavior matters because same-origin routing makes the agent easy to reach from the app, but route protection still decides who is allowed to use it. Sources: docs/guides/frontend/nuxt.mdx

To customize that policy, add agent/channels/eve.ts and export your own channel definition. Keeping the auth policy in the agent directory makes it part of the same filesystem-first surface as instructions and tools. For internal apps, you typically replace or extend the default policy with tenant-aware or user-aware checks. For a public demo, the Nuxt guide notes that none() from eve/channels/auth can skip authentication, but that should be a deliberate choice rather than an accidental result of not defining a channel. Sources: docs/guides/frontend/nuxt.mdx

agent/channels/eve.ts
import { eveChannel } from "eve/channels/eve";
import { localDev, vercelOidc } from "eve/channels/auth";
 
export default eveChannel({ auth: [vercelOidc(), localDev()] });

Dev, Deploy, and Non-Vercel Topology

During local development, the Nuxt workflow runs npm run dev, starts the eve dev server next to nuxt dev, and proxies eve routes through the Nuxt server. From the browser’s perspective, every request still targets the Nuxt origin. This is why the client binding can omit a host: the integration has already arranged for the public session endpoints to be available at the same origin. The same concept applies to SvelteKit, where the Vite plugin participates in the development server setup. Sources: docs/guides/frontend/nuxt.mdx

On Vercel, the intended topology is one project containing both the frontend app and the eve runtime. The web app remains public, while the runtime sits behind it on the same origin. If the agent requires a separate build step, set eveBuildCommand so the integration knows how to build the eve side of the project. This keeps deployment wiring near the framework config rather than scattering it across application code and environment-specific client URLs. Sources: docs/guides/frontend/nuxt.mdx

export default defineNuxtConfig({
  modules: ["eve/nuxt"],
  eve: {
    eveBuildCommand: "npm run build:eve",
  },
});

For non-Vercel hosts, Nuxt can point at a separate eve origin with EVE_NUXT_PRODUCTION_ORIGIN. For local production previews, the guide documents EVE_NUXT_PRODUCTION_PORT, with 4274 as the default local port. These variables are build-time topology controls, not component-level configuration. Keep them in deployment configuration and leave component code using the same useEveAgent call so local, preview, and production behavior stay aligned. Sources: docs/guides/frontend/nuxt.mdx

EVE_NUXT_PRODUCTION_ORIGIN=https://agent.example.com npm run build
EVE_NUXT_PRODUCTION_PORT=5000 npm run build && npm run preview

Compact Reference

AreaNuxtSvelteKitVueSvelte
Integration entry pointmodules: ["eve/nuxt"]eveSvelteKit() before sveltekit()Use eve/vue in a Vue appUse eve/svelte in a Svelte app
Component bindingAuto-imported useEveAgent in NuxtImport useEveAgent from eve/svelteImport useEveAgent from eve/vueImport useEveAgent from eve/svelte
Default agent locationagent/ in project rootagent/ in project rootDetermined by host integrationDetermined by host integration
Agent root overrideeve.eveRooteveRoot plugin optionNot a standalone routing optionNot a standalone routing option
Agent build overrideeve.eveBuildCommandeveBuildCommand plugin optionNot a standalone routing optionNot a standalone routing option
Browser host configNone for same-origin Nuxt moduleNone for same-origin SvelteKit pluginUsually inherited from framework mountingUsually inherited from framework mounting

The key rule is to configure topology at the framework integration layer, not inside the component. Components should call useEveAgent, observe status, send turns, and render streamed data. Framework config should decide where the agent directory lives, whether the agent has a build command, and how production traffic reaches the runtime. If you keep those responsibilities separated, the same chat UI can move from local development to Vercel or a non-Vercel deployment with minimal changes.

Next Steps

Start with the framework integration that matches your app: Nuxt uses eve/nuxt, while SvelteKit uses eve/sveltekit. Then read the matching useEveAgent page for the client binding you are using, because that reference covers returned state, events, send, stop, and reset behavior in more detail. If the app will be exposed beyond localhost, define agent/channels/eve.ts early and review route protection before shipping. For deployment work, verify eveRoot, eveBuildCommand, and any production-origin environment variables in the same change that adds the frontend integration.