Add a Voice AI Agent to a React App (2026 Guide)
Add the AnveVoice voice agent to a React single-page app: index.html for Vite and Create React App, a useEffect loader, Strict Mode and routing notes.
How to add AnveVoice to a React app
For a client-side React app, paste the AnveVoice script tag into the HTML page that React mounts into: index.html at the root of a Vite project, or public/index.html in an older Create React App project. Next.js and React Router framework apps have their own guides. Steps checked against the official documentation on 2026-10-14.
At a glance
- Where the code goes: Vite: index.html at project root. Create React App: public/index.html
- Coding needed: One line of HTML, or a short useEffect component if you want to control when it loads
- Plan limits: None from React. Free AnveVoice plan is enough
- Time: About 2 minutes plus a rebuild
Pick your setup first
React itself ships no HTML page, so where the tag goes depends on your tooling. React's documentation for building an app from scratch points to Vite, Parcel and Rsbuild as the build tools for a client-only single-page app, and recommends a framework once you need routing or data fetching. Its Create React App announcement says that tool is deprecated for new projects but still works in maintenance mode, so you may meet it in older codebases. If your project uses Next.js, use the Next.js guide. If it uses React Router's framework mode, use the React Router guide. Both generate their HTML from a root component rather than from a static file. This page covers the single-page setups.
- 1. Copy the install tag — Create a bot at app.anvevoice.app, copy its embed ID and substitute it below. &position=bottom-left and &theme=dark are optional. Code: <script src="https://anvevoice.app/embed.js?embedId=YOUR_EMBED_ID" async></script>
Method 1: the HTML page
In Create React App only, %PUBLIC_URL% is replaced at build time. Do not put it in the AnveVoice URL; the tag uses a full https address.
- 1. Vite (npm create vite@latest with the react template) — Open index.html in the project root, the file Vite treats as your entry point. Paste the tag above the closing body tag, below the div id="root" and the module script.
- 2. Create React App — Open public/index.html. The docs describe this file as editable and say the build adds your app's own script tag automatically. Paste the AnveVoice tag before the closing body tag. Manual script tags are described there as a workaround for less common cases, and a hosted widget script is exactly that.
- 3. Start or rebuild — Run your dev script (npm run dev or npm start) and reload. For production, run the build script and deploy the output folder.
Method 2: a component that loads the script
A component gives you control: load only in production, only for logged-out visitors, or only with an ID from your environment config. React's own guidance for effects is that code reaching outside React belongs in useEffect, and that in development Strict Mode deliberately mounts, unmounts and remounts every component once to expose effects that are not repeatable. This loader is built for that: it checks for an existing tag first, so the second run does nothing. There is no cleanup function on purpose. Removing the script element would not remove a widget that has already started, so the safest cleanup is to keep a single tag for the life of the page.
- 1. Create AnveVoice.jsx — Render it once near the root of the app. Code: import { useEffect } from 'react'; export function AnveVoice({ embedId }) { useEffect(() => { if (!embedId) return; const src = `https://anvevoice.app/embed.js?embedId=${embedId}`; if (document.querySelector(`script[src="${src}"]`)) return; const s = document.createElement('script'); s.src = src; s.async = true; document.body.appendChild(s); }, [embedId]); return null; }
- 2. Mount it — Add <AnveVoice embedId={import.meta.env.VITE_ANVEVOICE_EMBED_ID} /> inside your top-level App component. On Create React App use process.env.REACT_APP_ANVEVOICE_EMBED_ID instead. The ID is public in any case, since it is part of the script URL.
Routing and rendering notes
- Client-side routing does not reload the page, so a tag loaded once persists across routes. Do not place the loader inside a route component or it will run again for every visit to that route.
- Strict Mode double-invokes effects only in development. The querySelector guard is what keeps the tag from appearing twice there; in production the effect runs once.
- If you server-render with a framework, do not rely on this page. Effects never run on the server, so the tag would only appear after hydration in the browser.
- Content that React renders inside its root div is separate from the body-level tag, so React re-renders never remove the voice button.
Check that it works
- 1. Load the app in a private window — Deployed sites need HTTPS for microphone access; localhost is fine.
- 2. Find the button — A round microphone button appears bottom-right. Click it and allow the microphone.
- 3. Count the tags — In DevTools, run document.querySelectorAll('script[src*="anvevoice.app"]').length. It should return 1.
Common problems
- Button never appears with Method 2 in dev: the embed ID variable is undefined. Vite only exposes variables starting with VITE_ and needs a restart after editing an env file.
- Two buttons: you added both the HTML tag and the component. Use one.
- Edited public/index.html in a Vite project: Vite ignores it. The live file is the root index.html.
- Script blocked: a Content Security Policy on your host must allow https://anvevoice.app.
Sources
- React docs: build a React app from scratch (https://react.dev/learn/build-a-react-app-from-scratch) — checked 2026-10-14
- React docs: synchronizing with Effects (https://react.dev/learn/synchronizing-with-effects) — checked 2026-10-14
- React blog: sunsetting Create React App (https://react.dev/blog/2025/02/14/sunsetting-create-react-app) — checked 2026-10-14
- Create React App docs: using the public folder (https://create-react-app.dev/docs/using-the-public-folder/) — checked 2026-10-14
- Vite docs: getting started and env variables (https://vite.dev/guide/env-and-mode.html) — checked 2026-10-14
Related
- How to add AnveVoice to a Vue app
- How to add AnveVoice to an Angular application
- How to add AnveVoice to a Next.js app
- How to add AnveVoice to a React Router app
Try AnveVoice on your site
Free plan: $0, 50,000 tokens a month, no card. Get your embed ID in the dashboard, then paste one tag.