Next.js (Pages Router) quickstart
Add a Web Agent to a Next.js app that uses the Pages Router. At the end, the agent's launcher is on every page and the agent knows which user is signed in, from a token an API route of your app signs.
The adapter that lets the agent call Server Actions needs the App Router and is not part of this quickstart. In a Pages Router app the agent calls your API routes under pages/api and external APIs.
Prerequisites
- Next.js 14 or later with the Pages Router, and React 18 or later.
- A Web Agent in your workspace, created with Next.js as its technology, whose analysis has finished, with a version deployed to Production.
1. Copy your agent ID
- In the portal, go to Web Agents and select your agent.
- In the Overview tab, find the Install the assistant card and select By hand.
- In the Mount step, select Show snippet and copy the
agentIdvalue. The rest of the snippet is for the App Router.
2. Install the packages
npm install @faustine-ai/next @faustine-ai/web-agentpnpm add @faustine-ai/next @faustine-ai/web-agentyarn add @faustine-ai/next @faustine-ai/web-agentbun add @faustine-ai/next @faustine-ai/web-agent3. Mount the agent
Render <FaustineAgent> once in pages/_app.tsx, next to the page component.
import type { AppProps } from 'next/app';
import { FaustineAgent } from '@faustine-ai/next/client';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<FaustineAgent agentId="<AGENT_ID>" />
</>
);
}The component loads the Production environment. To load another one, pass its name: env="Staging".
4. Identify the signed-in user
The Pages Router has no root layout that runs only on the server, so the token is signed in an API route and fetched after the page mounts.
Copy the agent's secret from the Settings tab, under Identity verification, and add it to your server environment as FAUSTINE_IDENTITY_SECRET. Do not give the variable a NEXT_PUBLIC_ prefix.
Add the API route. getSession stands for your own session helper.
import type { NextApiRequest, NextApiResponse } from 'next';
import { faustineIdentityToken } from '@faustine-ai/next';
import { getSession } from '../../lib/session';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const user = await getSession(req);
const jwt = user
? faustineIdentityToken({ id: user.id, name: user.name, email: user.email })
: null;
res.setHeader('Cache-Control', 'no-store');
res.status(200).json({ jwt });
}Fetch the token in _app.tsx and pass it to the component.
import type { AppProps } from 'next/app';
import { useEffect, useState } from 'react';
import { FaustineAgent } from '@faustine-ai/next/client';
export default function App({ Component, pageProps }: AppProps) {
const [identityJwt, setIdentityJwt] = useState<string | null>(null);
useEffect(() => {
fetch('/api/faustine-identity')
.then((res) => res.json())
.then((data) => setIdentityJwt(data.jwt))
.catch(() => setIdentityJwt(null));
}, []);
return (
<>
<Component {...pageProps} />
<FaustineAgent agentId="<AGENT_ID>" identityJwt={identityJwt} />
</>
);
}The widget starts as anonymous and the component identifies the user when the token arrives. faustineIdentityToken signs an HS256 token that expires after 3600 seconds. Only id is required.
5. Run your app
npm run devCheckpoint
The agent's launcher appears on the page and stays after you move to another page. Sign in, select the launcher and send a message. In the portal, the conversation appears under the agent's Monitoring tab, with your name and a Verified badge.
Install with a coding agent
The install-faustine skill detects the Pages Router and does steps 2 to 4 in your repository.
npx skills add faustine-ai/skillsThen, in your coding agent:
/install-faustine <AGENT_ID>Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
/api/faustine-identity answers 500, and the server log has an error that starts faustineIdentityToken: set FAUSTINE_IDENTITY_SECRET |
The server environment has no secret. | Add the variable to .env.local and restart the dev server. |
No launcher, and the request to webagent.faustine.ai/embed returns 404 |
No environment of the agent serves a version. | Publish a version. |
No launcher, and the same request returns 403 |
The page's domain is not in the environment's allowed domains. | See Restrict the domains that can load the agent. |
| The user stays anonymous after signing in | The app fetched the token before the session existed and did not fetch it again. | Fetch /api/faustine-identity again after sign-in and set the new token. |
Next steps
- Next.js on Faustine: what each router supports.
- Identity verification: what a verified user gets.
- Restrict the domains that can load the agent: allow your own domains only.
- Next.js (App Router) quickstart: the same install with the token signed in the root layout.
Last updated November 11, 2026