Live chat widget
Add the Vocenya website live chat with one script tag, control it with the JavaScript API, and answer chats from your own systems.
The Vocenya live chat puts your AI receptionist on your website: it answers visitors, captures leads and hands the chat to a person when it should. Installing it is one script tag with your business's public site key, found in the portal under Live chat → Install.
The instructions below are the same ones Vocenya gives to AI site builders such as Lovable, Bolt, v0 and Cursor. Each business also gets its own copy with its key filled in, at /chat/{site key}/install.md, and the generic version is at https://vocenya.com/developers/chat-install.md. The portal's install page can copy a ready-made prompt or open it in ChatGPT or Claude for you.
What to add
Add this script tag once, so it loads on every page, just before the closing </body> tag (or the framework equivalent below):
<script src="https://vocenya.com/api/chat/widget.js" data-key="pk_YOUR_SITE_KEY" async></script>Replace pk_YOUR_SITE_KEY with the site key from the Vocenya portal (Live chat → Install). Each business has its own key.
The chat bubble then appears in the corner of every page. Nothing else is required.
Rules
- Load the script once, site-wide, in the shared layout or template. Not per page and not twice.
- Load it from https://vocenya.com/api/chat/widget.js exactly. Do not download, bundle, self-host, inline, minify or proxy the script: it is updated on our side.
- Do not change, remove or invent the
data-keyvalue. - Keep
asyncand do not addtype="module". - It is browser-only. Keep it out of server-only code paths (server components' logic, API routes, SSR data loaders, edge functions). Never call
window.Vocenyaduring server rendering; call it only in the browser, from event handlers or effects. - Do not install an npm package for it: there is none. Do not add a chat component of your own.
- If the site sends a Content Security Policy, add the sources below rather than loosening the policy any further.
Where it goes, by framework
Plain HTML or any server-rendered template
Paste the tag just before </body> in the template every page shares (footer include, base layout, theme.liquid, etc.).
Next.js (App Router)
In the root layout app/layout.tsx, use next/script with strategy="afterInteractive", inside <body>:
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://vocenya.com/api/chat/widget.js" data-key="pk_YOUR_SITE_KEY" strategy="afterInteractive" />
</body>
</html>
);
}Pages Router: put the same <Script> in pages/_app.tsx.
Vite + React (Lovable, Bolt, v0 exports, Replit and most AI-built React apps)
Add the tag to index.html at the project root, just before </body>. Not inside a React component.
Vue (Vite) and Nuxt
Vue with Vite: add the tag to index.html before </body>. Nuxt: add it with useHead in app.vue (or app.head.script in nuxt.config.ts):
useHead({ script: [{ src: 'https://vocenya.com/api/chat/widget.js', 'data-key': 'pk_YOUR_SITE_KEY', async: true, tagPosition: 'bodyClose' }] });SvelteKit
Add the tag to src/app.html, just before </body>.
Astro
Add the tag to the base layout every page uses (for example src/layouts/Layout.astro), just before </body>, with is:inline so Astro does not bundle it:
<script is:inline src="https://vocenya.com/api/chat/widget.js" data-key="pk_YOUR_SITE_KEY" async></script>Remix and React Router (framework mode)
In app/root.tsx, inside <body> next to <Scripts />:
<script src="https://vocenya.com/api/chat/widget.js" data-key="pk_YOUR_SITE_KEY" async></script>Webflow, Framer, Wix, Squarespace and other site builders
Use the site-wide custom code setting, not a page embed:
- Webflow: Site settings → Custom code → Footer code. Publish.
- Framer: Site settings → General → Custom code → End of tag. Publish.
- Wix: Settings → Custom code → Add custom code, All pages, Load once, Body - end.
- Squarespace: Settings → Advanced → Code injection → Footer.
- WordPress: use the Vocenya Chat plugin from the Vocenya portal, or the theme footer.
Content Security Policy
Only if the site sets a Content-Security-Policy (header or meta tag), add these sources to the existing directives:
script-src https://vocenya.com
connect-src https://vocenya.com wss://ws.vocenya.com
img-src https://vocenya.com
frame-src https://vocenya.comconnect-src covers the chat API and the live-reply websocket. frame-src is only needed if you also embed the hosted chat page in an iframe.
Optional: the JavaScript API
Only if asked. To call the chat before the script has loaded, add this stub above the script tag; calls are queued and replayed:
<script>window.Vocenya = window.Vocenya || function () { (window.Vocenya.q = window.Vocenya.q || []).push(arguments); };</script>Vocenya('open'),Vocenya('close'),Vocenya('toggle'): control the chat window.Vocenya('identify', { name, email, phone }): prefill a signed-in visitor so the team sees who they are.Vocenya('on', 'message' | 'open' | 'close' | 'lead', callback)andVocenya('off', event, callback): listen for chat events.
A "Chat with us" button:
<button type="button" onclick="window.Vocenya && window.Vocenya('open')">Chat with us</button>Identify a logged-in user in React (browser only):
useEffect(() => {
if (user) {
window.Vocenya?.('identify', { name: user.name, email: user.email });
}
}, [user]);In TypeScript, declare it once: declare global { interface Window { Vocenya?: (...args: unknown[]) => void } }.
Allowed domains
The chat only runs on the domains listed under Live chat → Install in the Vocenya portal. Make sure the site's live domain is on that list; preview or staging domains (for example *.lovable.app or *.vercel.app) must be added too if the chat should work there.
Check it worked
- Publish or deploy the site.
- Open the live site in a private window: a chat bubble appears in the corner. Click it and send a test message.
- No bubble? Open the browser console: look for a blocked script or connection (Content Security Policy) or a domain that is not allowed.
- Within a few minutes the Vocenya portal shows the chat as "Installed".
When you are done
Tell the owner which file you changed and confirm the script tag is unchanged. Docs: https://vocenya.com/developers/chat-install.md
Answer chats from your own systems
The chat is also part of the API, so a bot or your help desk can take part:
- Subscribe a webhook endpoint to
chat.message.created(scopechats:read). - Reply with
POST /chats/{chat}/messages(scopechats:write). Replies show in the visitor's widget straight away, from "Team". Replying to a chat the AI is answering takes it over, so the AI stops answering. - Skip messages with
via_api: true: they are your own replies. - Close the chat with
POST /chats/{chat}/closewhen you are done.
Replies are limited to 30 a minute per key. See the Chats reference and the live chat events.
Channels: website and WhatsApp
Chats come from two channels, and the API treats them the same way. Every chat and every chat.* webhook payload has a channel:
web: the website widget.page_urlis the page the visitor was on, andcontact_addressisnull.whatsapp: a customer messaging the business's WhatsApp number.contact_addressis the customer's number in E.164 (for example+15550102030), andpage_urlisnull.
WhatsApp only allows free-form replies within 24 hours of the customer's last message. reply_window_open on a WhatsApp chat tells you whether that window is open. Outside it, POST /chats/{chat}/messages is refused with 422 and code whatsapp_window_closed, plus a hint. Follow up with an approved template from the Vocenya inbox instead. Templates only go to customers who opted in to WhatsApp messages and have not replied STOP.
WhatsApp is not available to HIPAA-mode accounts.