React quickstart

Add a Web Agent to a React single-page app. At the end, the agent's launcher is on every page of your app and the agent knows which user is signed in.

Prerequisites

  • A React app built with Vite or another bundler.
  • A Web Agent in your workspace whose analysis has finished, with a version deployed to Production.

1. Copy your agent ID

  1. In the portal, go to Web Agents and select your agent.
  2. In the Overview tab, find the Install the assistant card and select the npm tab.
  3. Copy the agentId value from the snippet.

2. Install the loader

terminal
npm install @faustine-ai/web-agent

The package is a loader of about 9 KB gzipped. It fetches the widget and your agent's served version from Faustine when the page loads, so a version you deploy in the portal reaches your users without a new build of your app.

3. Start the agent

Create a module that starts the agent once, and import it from your entry file.

src/faustine.ts
import Faustine from '@faustine-ai/web-agent';

export const agent = Faustine.init({
  agentId: '<AGENT_ID>',
});
src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import './faustine';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

init loads the Production environment. To load another one, pass its name: env: 'Staging'.

4. Identify the signed-in user

Call identify when your app knows who the user is, and logout when they sign out. This example passes a display name and email, which appear in the agent's Monitoring tab as Unverified.

src/useFaustineUser.ts
import { useEffect, useRef } from 'react';
import { agent } from './faustine';

type User = { id: string; name: string; email: string };

export function useFaustineUser(user: User | null) {
  const signedIn = useRef(false);
  useEffect(() => {
    if (user) {
      agent.identify({ userId: user.id, name: user.name, email: user.email });
      signedIn.current = true;
    } else if (signedIn.current) {
      agent.logout();
      signedIn.current = false;
    }
  }, [user]);
}

The hook calls logout only after a user has been identified, so a visitor who never signs in keeps their conversation. Call it from the component that holds your session. useSession and Routes stand for your own session hook and routes.

src/App.tsx
import { useSession } from './session';
import { useFaustineUser } from './useFaustineUser';

export default function App() {
  const { user } = useSession();
  useFaustineUser(user);
  return <Routes />;
}

For production, replace the labels with a token signed by your backend. See Verify your users with a signed token.

5. Run your app

terminal
npm run dev

Checkpoint

The agent's launcher appears on the page. Select it and send a message. In the portal, the conversation appears under the agent's Monitoring tab.

Install with a coding agent

The install-faustine skill does steps 2 to 4 in your repository and follows its conventions.

terminal
npx skills add faustine-ai/skills

Then, in your coding agent:

/install-faustine <AGENT_ID>

Install without a build step

If you cannot add a dependency, load the widget from a script tag in index.html. The JS / Auto tab of the Install the assistant card has this snippet with your ID filled in.

index.html
<script src="https://webagent.faustine.ai/embed?wid=<AGENT_ID>" async></script>

Troubleshooting

Symptom Cause Fix
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 console shows init called for "…" but "…" is already initialized init ran twice with different IDs. A page holds one agent. Call init in one module only.

Next steps

Last updated November 13, 2026