Add a Voice AI Agent to a Docusaurus Site (2026)
Add the AnveVoice voice agent to a Docusaurus docs site with the scripts field in docusaurus.config: async loading, client-side navigation, dev vs build.
How to add AnveVoice to a Docusaurus site
Docusaurus has a purpose-built option for this. Add the AnveVoice URL to the scripts array in docusaurus.config.js (or .ts) with async set to true, then rebuild. Docusaurus inserts the tag in the head of every page it generates. Steps checked against the official documentation on 2026-10-14.
At a glance
- Where the code goes: The scripts array in docusaurus.config.js or docusaurus.config.ts
- Coding needed: A few lines in the config file; no React code
- Plan limits: None from Docusaurus. Free AnveVoice plan is enough
- Time: About 2 minutes plus a build
The scripts field
Docusaurus's configuration reference defines scripts as an array of scripts to load, where each value is a string or an object of attributes. The tags are inserted into the HTML head, and an object needs only a src plus any extra attributes you want. The same page warns that scripts added this way are render-blocking, so it suggests adding async: true or defer: true to the objects. AnveVoice's tag is async by design, so use the object form to keep that behaviour. This is simpler than swizzling a theme component or overriding the HTML template, and it survives Docusaurus upgrades, so stay with it unless you need something conditional.
- 1. Get your embed ID — Create a bot at app.anvevoice.app and copy the embed ID from the dashboard. The tag you are reproducing looks like this. Code: <script src="https://anvevoice.app/embed.js?embedId=YOUR_EMBED_ID" async></script>
Method 1: add it to docusaurus.config
The config file is docusaurus.config.js, or docusaurus.config.ts in a TypeScript project, in the site root next to package.json. Docusaurus 3.x requires Node.js 20 or newer to build.
- 1. Open the config file — Find the object you export. Keep your existing title, url, presets and themeConfig exactly as they are.
- 2. Add the scripts entry — Put it at the top level of the exported config, beside title and url. If you already have a scripts array, add this object to it. Code: const config = { // ...title, url, baseUrl, presets, themeConfig scripts: [ { src: 'https://anvevoice.app/embed.js?embedId=YOUR_EMBED_ID', async: true, }, ], }; export default config;
- 3. Restart and build — Restart npm run start so the config reloads. For production, run npm run build; the installation guide says the static site is written to the build folder.
Method 2: only in production builds
Because the config file is JavaScript that runs in Node, you can decide at build time whether to include the script. Docusaurus runs the development server and the production build in different Node environments, so a NODE_ENV check keeps the voice button off your local preview of the docs.
- 1. Make the entry conditional — Spread an empty array when not in production. Code: scripts: [ ...(process.env.NODE_ENV === 'production' ? [{ src: 'https://anvevoice.app/embed.js?embedId=YOUR_EMBED_ID', async: true }] : []), ],
Single-page navigation
Docusaurus is a single-page app. Its client-modules documentation points out that module scripts do not re-run on page transitions, and provides onRouteUpdate and onRouteDidUpdate hooks for code that must run on every navigation. The AnveVoice tag does not need those hooks: the script loads once with the first page, and the button stays mounted while visitors browse the docs. Do not try to re-add it per route. The same page says client modules are called during server-side rendering as well, which is why browser-only code needs a guard. Another reason to prefer the scripts field here: it needs no such guard.
Docusaurus-specific gotchas
- headTags is a related option, but its documentation shows only a link example, so use scripts for a script.
- Versioned docs, i18n locales and the blog all share the same config, so one entry covers them all.
- The baseUrl does not affect the tag, because the AnveVoice URL is absolute.
- A Content Security Policy added by your host or a reverse proxy must allow https://anvevoice.app in script-src and connect-src.
- Search crawlers and the Algolia DocSearch box are unaffected; the voice agent is an additional widget, not a replacement for search.
Check that it works
- 1. Build and serve locally — Run npm run build, then serve the build folder with npm run serve. With Method 2, the script only appears in this production-style preview.
- 2. Search the output — Open build/index.html and look for anvevoice.app inside the head.
- 3. Open a doc page and click the button — Use a private window on the deployed HTTPS site, click the round microphone button at bottom-right and allow the microphone.
Common problems
- Config error after editing: the scripts array sits inside themeConfig. It must be a top-level key.
- No button in npm run start: you used Method 2. Test with a production build instead.
- Still the old behaviour after deploying: your host or CDN is caching HTML. Purge it, then reload with a hard refresh.
- Button flickers or appears late: an adblocker or a slow connection is delaying the script. It is async, so the docs render first.
- Two buttons: you added the tag in a custom src/theme file as well. Keep only the config entry.
Sources
- Docusaurus docs: docusaurus.config.js (scripts, headTags) (https://docusaurus.io/docs/api/docusaurus-config) — checked 2026-10-14
- Docusaurus docs: client architecture (client modules, route hooks) (https://docusaurus.io/docs/advanced/client) — checked 2026-10-14
- Docusaurus docs: installation (Node version, build folder) (https://docusaurus.io/docs/installation) — checked 2026-10-14
Related
- How to add AnveVoice to a VitePress site
- How to add AnveVoice to a MkDocs documentation site
- How to add AnveVoice to a Hugo site
- How to add AnveVoice to a plain HTML website
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.