Back to all posts
EngineeringJuly 22, 202610 min readUpdated October 12, 2026

Building an embeddable chat widget in one script tag

One script tag is the easy part to promise and the hard part to actually ship without breaking someone else's website. Here's what that one tag has to do.

AI
The Aiva Chat team
Aiva Chat
A laptop on a white table showing code
Photo by AltumCode on Unsplash

"Paste one script tag" is an easy line to put on a marketing page and a genuinely hard constraint to design against. Every business that installs Aiva Chat's web widget is dropping our code into a site we've never seen, built on a stack we don't control: WordPress, Webflow, a hand-rolled React app, or a Shopify theme with six plugins already fighting each other.

An embeddable chat widget has to work identically on all of them, without the business touching anything beyond pasting a snippet once. If it breaks the host page's layout, slows it down, or leaves an error in the corner of someone's homepage, the business blames the widget, and they're right to.

Most of the engineering goes into one question: what should happen when our code meets a page we've never seen and something on it misbehaves? The answers shape everything from how the tag finds itself to what a visitor sees when a file fails to load.

It's written for the curious owner and for whoever ends up pasting the snippet. You don't need to be a developer to follow it, and you don't need one to install the widget, which is the whole point.

What is an embeddable chat widget?

An embeddable chat widget is a small piece of software that adds a chat window to any website through a snippet of code. Visitors click a bubble in the corner and start a conversation without leaving the page.

Aiva Chat's web widget connects that bubble to the same assistant that answers your phone. Visitors can type, or talk by voice in the browser if you allow it. It answers from your business information, books appointments, captures leads, and hands off to a person when needed.

The visible part is small on purpose:

<script src="https://chat-widget.aivachat.io/embed.js" data-user-id="YOUR_USER_ID" data-assistant-id="YOUR_ASSISTANT_ID"></script>

The two IDs say "this page belongs to this business, and this assistant answers." Everything else, including appearance, greeting, auto-open behavior, and pre-chat questions, is configuration loaded from those IDs at runtime. Nothing the business wants to change later lives in the tag.

It suits any business with a website and visitors who have questions: clinics, salons, home services, law firms, and online stores. The widget is one adapter into the same conversation engine that answers phone calls.

How the one-tag embed works

Step 1: The script finds its own tag

When the script runs, it looks for the tag that loaded it and reads the two data attributes. If either ID is missing, it logs a quiet warning to the browser console and stops. No broken placeholder appears on the page.

Step 2: It waits for the page

If the page is still loading, the widget waits until the document is ready before mounting. Combined with placing the tag just before the closing body tag, the host page's own content is in place before the widget does anything.

Step 3: It builds a sealed container

The script adds one host element to the page and attaches a Shadow DOM to it. Everything the widget renders lives inside that boundary, positioned above the page so it doesn't push your content around.

Step 4: It loads the business's settings

Inside the container, the widget loads the configuration for that assistant: branding, colors, position, welcome message, pre-chat form, and whether voice is allowed. It only runs on domains the business has added to its allowed websites list.

Step 5: Heavy parts load only when needed

The 3D visual for voice mode lives in a separate file that's downloaded the first time a visitor starts a voice conversation. If that file can't load, voice still works with a simpler animated circle instead.

Why this design matters for the business

Changes never need a redeploy

Because behavior lives in configuration, a business can change its greeting or colors in the dashboard and the next page load picks it up. The snippet almost never needs to be touched after the first paste. We've written about adding the widget without a developer, and this split is the engineering reason that's possible.

The host site's design stays intact

A host site's CSS resets, its font declarations, and its global box-sizing rules don't touch the widget's layout. The widget's styles can't leak out either. That's what makes "works on any site" true rather than "works on the sites we tested."

Mistakes are forgiving

Businesses paste snippets into tag managers, theme widgets, and page builder blocks, sometimes twice. A second embed on the same page replaces the first rather than mounting two bubbles, so a duplicate install doesn't produce a doubled widget.

Failures stay quiet

If the snippet is missing an ID, the script logs a console warning and adds nothing to the page. If the widget's settings can't be fetched, it falls back to its default look instead of throwing a visible error. A business's site should never look broken because of us.

Branding is fully controllable

Header, colors, font, light or dark theme, size, position, and the "Powered by" line are all settings. Our post on custom branding for the web widget goes through the options.

The hardest widget bugs usually trace back to some other script on the host page, added years ago, that nobody at the business remembers is there. Defensive code against an unknown host environment is most of the engineering here.

Where the one-tag constraint gets tested

Four host-page situations the design has to survive, described as general patterns rather than particular sites.

The page builder with a dozen plugins

Problem: A salon's site runs a page builder, a slider plugin, and a theme with aggressive global CSS. How the widget handles it: Shadow DOM isolation means none of those styles reach the widget, and the script locates its own tag by its data attributes even inside builder markup. Outcome: The widget looks the same as it does in the dashboard preview.

The double install

Problem: A clinic adds the snippet through its tag manager, then a staff member pastes it into the theme footer too. How the widget handles it: The second embed replaces the first. Outcome: One chat bubble, not two, while the clinic tidies up its install.

The strict security policy

Problem: A law firm's site sends a Content Security Policy that only allows approved external scripts. How the widget handles it: It can't route around a policy, so this is the one case where the site's developer adds the widget's script and font sources to the policy. We document exactly what's needed. Outcome: A one-time configuration change, after which the widget runs normally.

The phone visitor

Problem: Most visitors arrive on phones, where a desktop-sized bubble can crowd the screen or cover a phone number. How the widget handles it: The builder previews desktop and phone layouts side by side, and size and position are configurable. Outcome: The business checks the phone view before going live instead of discovering problems from visitors.

Script tag vs. installable package vs. iframe embed

One script tag (Aiva Chat)Installable packagePlain iframe embed
Who can install itAnyone who can edit a footerA developer with a build setupAnyone who can edit a page
Changing appearance laterDashboard setting, no redeployCode change and redeployUsually a dashboard setting
Style isolationShadow DOMDepends on the packageStrong, separate document
Floating bubble over any pageYesYesAwkward, fixed-size box
Deep control for developersLimited, settings onlyFullVery limited
Works on hosted buildersYes, via custom code settingsRarelyYes

An installable package is the better choice for a development team that wants full control and ships code every week anyway. It's the wrong model for a clinic owner who wants to change a greeting without filing a request.

A plain iframe gives strong isolation, because the widget is a separate document. It's harder to make one behave like a floating bubble that opens and closes over any page layout, and it tends to sit in a fixed box.

A script tag with Shadow DOM sits between the two: anyone can install it, it floats naturally over the page, and the browser keeps the styles apart. MDN's guide to using shadow DOM explains the encapsulation it relies on.

How to install the widget on your site

The widget is part of Aiva Chat's six guided setup steps. The details live in the add the website widget guide.

Step 1: Design it in the Widget Builder

Pick the assistant that answers, then set the header, welcome message, colors, size, position, font, and theme. The live preview shows chat, voice, and pre-chat screens on desktop and phone.

Step 2: Decide on pre-chat and voice

Choose whether to ask for name, phone, and email before chatting, and whether visitors can talk by voice. Voice uses your OpenAI key and needs Realtime access on it.

Step 3: Add your allowed websites

List every domain where the widget should load, such as your main domain and a wildcard for subdomains. Until you add one, the widget won't load anywhere.

Step 4: Copy and paste the script

On the Install tab, copy the script and paste it just before the closing body tag in a shared footer or layout file. Each assistant has its own script, so copy it again if you switch assistants.

Step 5: Check it works

Use Check a website on the Install tab to confirm the domain is allowed, then open your site and look for the bubble. Try a question and a booking on your phone as well as your laptop.

Common embedding mistakes

Forgetting the allowed websites list

The most common "the widget doesn't show up" cause is a missing domain, often the www version. Add both, or use a wildcard for subdomains.

Pasting on one page only

Putting the script in a single page's content means the widget disappears everywhere else. Use a site-wide footer or layout setting so it appears on every page you want.

Installing through two tools

A tag manager plus a theme setting creates two places to manage the same widget. It won't double the bubble, but it confuses whoever edits the site next. Pick one place.

Ignoring a Content Security Policy

If your site restricts scripts and fonts, the widget won't load until those sources are allowed. Check your browser console for blocked requests and ask your developer to add the documented sources.

Never testing on a phone

A widget that looks fine on a laptop can cover a menu or phone number on a small screen. Preview the phone layout and adjust size or position before going live.

Widget embedding best practices

  • Use a shared footer or layout file. One paste covers the whole site.
  • Add every domain you use. Include www, staging, and subdomains as needed.
  • Keep one install location. Remove duplicates from tag managers or themes.
  • Set a sensible auto-open delay. Or leave it at zero so visitors open it themselves.
  • Turn off voice if you only need text. Voice runs on OpenAI's real-time model, priced separately from text chat.
  • Check the phone preview. Most visitors see that version first.
  • Connect what the widget books into. See Aiva Chat's integrations for calendars and CRMs.

Conclusion

The bet behind the one-tag design is that a business owner should never have to think about it after day one. Keeping every changeable thing in configuration, and keeping styles behind a Shadow DOM boundary, is what makes that bet hold on sites we've never seen.

The limit is that some host sites are built to refuse outside code, and no tag can route around that. If your site sends a strict Content Security Policy, plan for a short conversation with whoever maintains it, because the widget's script and font sources have to be allowed. That's the one install where you may still need a developer.

For everyone else, the work that matters is small: choose the single footer or layout file the tag will live in, and list every domain the site is served from before you paste.

Ready to add AI chat to your website?

Open the Widget Builder, match the bubble to your site, add your domains, and paste the tag into your footer. Then test it from your phone with the questions visitors usually email you.

The widget is included on every plan, starting with Starter at $49 a month, and its chat and voice replies run on your own OpenAI key. See the plans, or call +1 (970) 972-0974 to hear the same assistant on the phone.

To try it on your own site, start a 14-day free trial with no card, or book a demo if your site has a security policy you'd like us to look at first.

EngineeringVoiceML
Share
AI
Written by
The Aiva Chat team
Aiva Chat

Posts from the people building Aiva Chat in Rajkot — how the product works, what we have learned building it, and guides for getting the most out of an AI receptionist.

Rajkot, India · at Aiva Chat since 2024
More posts

FAQ

Common questions.

Still have questions?Contact us

Copy the script tag from the Install tab of the Widget Builder and paste it just before the closing body tag on every page where the widget should appear, usually in a shared footer or theme file. It works the same way on WordPress, Webflow, Shopify, Wix, Squarespace, or a hand-coded site. Then add your domain to the allowed websites list and save.

It's designed not to get in the way. The tag goes at the end of the page, the widget mounts once the page's own content is ready, and the heavier voice visual is only downloaded the first time a visitor starts voice mode. Visitors who never open the widget never load the voice code at all.

No. The widget renders inside a Shadow DOM, a sealed container the browser keeps separate from the rest of the page. Your site's CSS resets and font rules don't reach the widget's layout, and the widget's styles can't leak out and change your pages. The only page-wide addition is a font declaration link when you choose a web font.

You won't end up with two chat bubbles. A second embed on the same page replaces the first, which matters because businesses sometimes install the widget through a tag manager and a theme setting at the same time without realizing it. It's still worth removing the duplicate so there's one clear place to manage it.

No. The script tag is the only code involved. Greeting, colors, position, size, font, theme, pre-chat form, voice mode, and auto-open delay are all settings in the Widget Builder. Saved changes reach your live site the next time a page loads, so you never need to paste the script again after the first install.

Yes, that's what the design is built to survive. Shadow DOM isolation keeps other plugins' styles away from the widget, and the script finds its own tag by its data attributes even when a page builder wraps it in extra markup. If your site uses a strict Content Security Policy, your developer needs to allow the widget's script and font sources.

An installable package needs a developer and a build step every time something changes. That's the wrong model for a clinic or salon owner who wants the widget live today and wants to change its greeting themselves next month. With a script tag, everything that changes over the widget's life is a dashboard setting.

The widget only loads on websites you add to the allowed websites list in the Widget Builder. This stops someone copying your snippet onto their own site and using your assistant. If the widget doesn't appear, check that your domain is listed, including the www version if your site uses it, or add a wildcard to cover subdomains.

Like this? Get more.

One email a month. Guides, engineering deep-dives and product updates. No fluff.

4,200+ subscribers. Unsubscribe anytime.