Voxinly
Platform integrations

Adding Voxinly to a custom-built website

How to drop the Voxinly widget into a custom HTML, React, Next.js, Astro, Eleventy or any bespoke site — without breaking your build, your CSP, or your developer's day.

1 June 2026·7 min read·Voxinly team
A developer's laptop with code on screen, ready to paste a script tag

If your website was hand-built — straight HTML, a static-site generator, a React or Next.js app, an Astro or Eleventy build, or anything that doesn't have a one-click plugin marketplace — adding Voxinly is still a sixty-second job. The widget is a single line of JavaScript that mounts itself, so there's nothing for you to wire up beyond pasting it in the right place.

Step 1 — Grab your embed snippet

1

Open /admin/embed

Sign in to your Voxinly admin and click 'Embed code' in the sidebar. You'll see a one-line <script> tag with your tenant ID baked in. Copy it.

Step 2 — Paste it into your site

Plain HTML

Open your template (or every page if you don't share one) and paste the snippet just before the closing </head> tag. Save, redeploy, done.

Next.js (App Router)

Open src/app/layout.tsx and add the Next.js <Script> component inside the <html> tree with strategy='afterInteractive'. The widget only needs to load after hydration, so afterInteractive is the right strategy — it keeps your Core Web Vitals clean.

Next.js (Pages Router)

Open pages/_document.tsx and paste the script tag inside the <Head /> block. If you'd rather defer it, use the Next.js Script component in pages/_app.tsx with strategy='lazyOnload' instead.

React (Vite / CRA)

Open public/index.html (CRA) or index.html (Vite) and paste the snippet inside <head>. You don't need a React wrapper — the widget mounts its own root.

Astro

Open src/layouts/Layout.astro (or whichever layout wraps every page) and paste the snippet inside the <head>. Astro doesn't need a special directive — it ships the script as-is.

Eleventy / 11ty

Open your base layout (usually _includes/base.njk or similar) and paste the snippet inside <head>. Rebuild, deploy.

Hugo

Open layouts/partials/head.html (or your equivalent) and paste the snippet at the end. Run hugo, deploy your public/ folder.

Step 3 — Content Security Policy (CSP)

If your site sets a strict CSP, you'll need to allow Voxinly's script origin and API endpoint. The two directives you'll usually need:

DirectiveAdd
script-srchttps://cdn.voxinly.com
connect-srchttps://api.voxinly.com https://*.supabase.co
img-srchttps://cdn.voxinly.com https://images.unsplash.com
frame-srchttps://wa.me

Step 4 — Customising programmatically

Most customers configure Voxinly entirely through the admin UI — colours, copy, knowledge, business hours. If you need to push values from your application (for example, the customer's email after they log in), use the global API:

  • window.__voxinly.identify({ email, name }) — link this visit to a known user
  • window.__voxinly.open() / .close() — programmatic widget control
  • window.__voxinly.on('lead', cb) — subscribe to events for your own analytics
  • window.__voxinly.config({ position: 'left' }) — runtime overrides for layout

Step 5 — Test in a private window

Open your deployed site in an incognito window. The chat bubble should appear bottom-right within a second of page load. Click it, ask a test question, watch the answer come back. Check your browser console for any CSP errors — those are the only thing that will silently break the widget on a custom build.

FAQ

Will Voxinly slow down my site?

The bootstrap script is around 9 KB gzipped and loads asynchronously. It does not block first paint, contentful paint, or interactive. Lighthouse scores are unchanged in real-world tests.

Does it work with Server Components?

Yes. The widget is a client-side bundle so it doesn't care whether your shell came from a server component or a static export — it mounts after hydration in either case.

Can I lazy-load it on a button click?

Yes. Remove the script tag from <head> and load it dynamically when your visitor clicks a 'Chat to us' button. The widget will boot, auto-open, and behave normally from there.

What if my site is behind a paywall or auth wall?

Voxinly works behind any auth wall — the script just needs to load on the page. Use identify() to pass the logged-in user's details if you want conversations linked back to a known customer.

Will it break if my CDN strips third-party scripts?

Yes — most aggressive CDNs (Cloudflare Rocket Loader, etc.) can mangle async scripts. Add data-cfasync='false' to the script tag to opt out of Rocket Loader specifically. We include this attribute by default.