Next.js on Faustine

Faustine supports Next.js for Web Agents, with the App Router and with the Pages Router. A Next.js agent is installed as a React component, signs the user's identity on your server, and with the App Router can call Server Actions through an adapter in your repository.

Get started

What each router supports

Feature App Router Pages Router
<FaustineAgent> component Yes, from the root layout Yes, from pages/_app.tsx
Identity signed on the server with faustineIdentityToken Yes, in the root layout Yes, in an API route
Routes read from the filesystem Yes Yes
Navigation through the Next.js router Yes Yes
Page re-rendered after the agent writes Yes No
Adapter for Server Actions and server-only functions Yes No

Analysis

The analysis finds the Next.js app in your repository by its package.json: the root of the repository, or a directory up to two levels below it, such as web/ or apps/site/. It reads which router the app uses from the app/ or pages/ directory, also under src/.

The list of routes comes from the files. The analysis writes a description for each one.

File Route
app/(marketing)/pricing/page.tsx /pricing
app/deals/[id]/page.tsx /deals/:id
app/docs/[...slug]/page.tsx /docs/:slug*
pages/users/[id]/settings.tsx /users/:id/settings

Route groups add no segment. Parallel routes (@slot), intercepting routes, folders that start with _ and everything under api are not listed as pages.

Route handlers (route.ts files under app/) are read as the app's own API, so the agent gets actions for them even when no client component calls them. See The analysis.

Sessions

When the app authenticates with a cookie session, the agent's requests are sent with the user's cookies. The agent acts as the signed-in user and sees what that user sees.

If the session has expired and a request ends on your sign-in page, the action fails with an error that says the user is not signed in.

Data surface

A Next.js app can keep its data where the browser has no URL to call. The analysis summary has a Data surface card that sorts the app's data access into Reachable now (route handlers and client-side fetches), Reachable with the adapter (Server Actions and server-only data functions) and Not reachable (reads written inline in a Server Component).

For a read in the last group, the card suggests the data function to extract. After you extract it and push, it moves to the second group.

Server Actions and the adapter

The Faustine adapter gives Server Actions and server-only data functions a URL inside your own app. npx faustine-next init writes a registry of the functions you expose and a route handler at app/api/faustine/[...op]/route.ts. The agent calls the handler from the browser with the user's cookies, and the handler runs only the operations that are in the registry and enabled in the portal.

The adapter needs the App Router. See The Faustine adapter for Next.js.

The agent moves between pages with the Next.js router, so the destination renders without a full page load. If the router is not on the page, the agent loads the destination with a full page load.

After every action that writes, the agent refreshes the current route. In the App Router this re-renders the Server Components of the current route, so the page shows what the agent changed. Several writes in one step refresh the page once. Every call through the adapter counts as a write. See Navigation.

Identity

faustineIdentityToken from @faustine-ai/next signs the user's identity token on your server with FAUSTINE_IDENTITY_SECRET, and <FaustineAgent identityJwt={…}> passes it to the widget. The secret never reaches the browser.

app/layout.tsx
import { faustineIdentityToken } from '@faustine-ai/next';

const identityJwt = user
  ? faustineIdentityToken({ id: user.id, name: user.name, email: user.email })
  : null;

See Identity verification.

Build SHA

withFaustine wraps your Next.js config and records the commit of the build, so the portal can show which commit the running app was built from. It is optional and only has an effect with the adapter.

next.config.ts
import type { NextConfig } from 'next';
import { withFaustine } from '@faustine-ai/next';

const nextConfig: NextConfig = {};

export default withFaustine(nextConfig);

The commit is read at build time from the first of these variables that is set: FAUSTINE_BUILD_SHA, VERCEL_GIT_COMMIT_SHA, GITHUB_SHA, CF_PAGES_COMMIT_SHA, COMMIT_REF, SOURCE_VERSION. The adapter's handler includes it in GET /api/faustine/manifest and in the x-faustine-build response header. In the portal, the Deployed cell under Settings > Faustine adapter shows its first 7 characters.

Environments

<FaustineAgent> loads the Production environment unless you pass env. The adapter's handler reads the enabled operations of Production unless FAUSTINE_ENV is set on the server. When a deployment serves another environment, set both to the same name.

More resources

Next steps

Last updated November 13, 2026