Add an AI Chatbot to Any Website or Framework
Hand-coded site or a modern framework? Add the AI support agent with one script tag before </body>. It works on static HTML, React, Vue, Next.js, and more.
What connecting a custom site gets you
Evoriqa is a single, framework-agnostic script, so it drops into any site: hand-coded static HTML, a templating engine, or a JavaScript framework like React, Vue, Angular, Svelte, or Next.js. There's no plugin and no platform lock-in: one line before the closing </body> tag and the agent is live, injecting its floating chat bubble automatically.
Because the script is async, it won't block your page from rendering, which matters most on the hand-built sites where you own the performance budget rather than a builder owning it for you.
| Without the agent | With the agent | |
|---|---|---|
| Adding chat to a bespoke stack | A vendor SDK to integrate | One script tag |
| A multi-route single-page app | Wired up view by view | Added once in the root layout |
| Page performance | Another blocking request | An async script that doesn't block render |
Scroll sideways for more columns
Where the snippet goes
The snippet, a single `<script>` tag carrying your `data-chatbot-id`, goes just before the closing </body> tag, in your site's HTML file or your framework's root layout or document template. That's the one spot that guarantees it loads on every page without being duplicated, and it's the same placement whether the page is static HTML or rendered by a framework.
If your platform already offers an end-of-body field, use that instead of editing a template — Ghost has one in Code Injection, and Bubble has one under SEO / metatags. A settings field survives theme and platform updates; an edited template doesn't always.
Before you start
You'll need access to your site's HTML or root template and your embed snippet from the Install tab, which already has your chatbot id filled in. If you don't have a workspace yet, create one free at app.evoriqa.com, no credit card needed, and the snippet is generated for you the moment your first agent exists.
Using a JavaScript framework?
For single-page apps — React, Vue, Angular, Svelte, Next.js, and the like — add the snippet once in your root layout or document template so it loads on every route rather than being mounted and unmounted per view. The script injects the chat bubble itself, so there's no component for you to render or state for you to manage; it just needs to be present in the document.
Prefer an inline search box?
If you'd rather embed an AI search bar in the page than float a bubble over it, copy the inline-search variant from the Install tab and drop its target element wherever you want the search box to appear. It's the same agent, presented inline instead of as a floating bubble, useful when the AI is meant to be part of the page rather than an overlay.
Confirming it's live
Deploy the site and open it in a fresh tab. On a static site the bubble appears as soon as the page loads; on a framework, navigate between a couple of routes to confirm it persists rather than disappearing on the first client-side navigation.
Common questions
Does it work with React, Vue, or Next.js? Yes. It's a single async, framework-agnostic script. Add it once in the root layout or document template and it loads on every route.
Will it slow my site down? It loads asynchronously, so it doesn't block the page from rendering. On a hand-built site that's one fewer render-blocking request to worry about.
Can I show a search bar instead of a bubble? Yes. Use the inline-search variant from the Install tab and place its target element where you want the search box, instead of the floating-bubble snippet.
Stack-specific limits
Because the widget loads a script from an external host, a site with a strict Content-Security-Policy will block it until that host is allowed. That's the kind of thing you only hit on hardened, hand-built sites, not on hosted builders that manage their own policy.
It takes two directives. The script in your snippet is a small loader: it frames a same-origin shell served from your Evoriqa domain, and the widget runs inside that shell. Everything the widget itself does — its scripts, its API calls, its styles, the in-chat booking calendar — runs under our policy, inside the frame, rather than under yours.
So you allow the origin your snippet loads from — the exact host in your embed snippet's <script src> — in two places. Swap <origin> for that host (your own branded domain if you were set up on one, otherwise the Evoriqa app origin):
script-src <origin>
frame-src <origin>Your chatbot's Install tab prints both lines with your origin already filled in, so copy them from there rather than typing them.
You never need to allow calendly.com or cal.com yourself, and you don't need a separate rule for a custom avatar or logo — those load inside the shell, under our policy, not yours.
If your policy refuses the frame anyway, nothing dies silently: the loader falls back to mounting the widget directly in your page, so visitors still get a working widget, and the blocked frame is reported back and shown as a banner on that chatbot's Install tab. Treat the banner as a to-do — the fallback puts the widget back under your page's policy, which is exactly what the shell exists to avoid.
Keep reading
Ready to add AI support to Custom HTML / JS?
Point Evoriqa at your website and help docs, and your agent starts answering questions, capturing leads and booking appointments across every channel. Free to start, no credit card.