Any website

An AI chat widget for any website that lets you add a script

An AI chat widget for any website needs one thing from you: the ability to put a script tag on the page. This page is for developers, agencies and technically minded owners with custom HTML, a single-page app or a Google Tag Manager container, and it covers placement, Content Security Policy, the JavaScript API and the usual ways installs go wrong.

1 async scriptloads without blocking your page
Shadow DOMyour CSS cannot break it, and it cannot break yours
Include it oncetwo copies make two launchers

The embed snippet for any website

Copy your own snippet from Sites in the dashboard; the placeholder below shows its shape. The site id is public, which is why the allowed-origins list exists.

<script src="https://cdn.sitetrellis.com/v/a44108d9c4521120/widget.js" data-site="site_XXXXXXXXXXXXXXXX" async></script>

Put it on every page where chat should be available, just before the closing body tag, usually in a shared layout or footer file. A real site id is site_ followed by 16 letters and digits; a malformed one makes the widget log a warning and stop. The HTML install guide lists every attribute.

One script, any stackStart free, add the snippet to your layout and verify it in the Network tab. No credit card.
Start free

Install steps in outline

  1. Publish an agent

    The widget stays hidden until the site has a published, enabled agent.

  2. Add allowed origins

    Use scheme, host and port with no path: https://www.example.com, a separate entry for the bare domain, https://*.example.com for subdomains, and http://localhost:3000 for development.

  3. Add the snippet once

    In the template, the root HTML of your app, or one Google Tag Manager tag, but not several.

  4. Verify

    Hard-refresh, check that widget.js returns 200 followed by a successful config request, then send a message and look for it under Conversations. The site page’s Run check button can also look for the snippet.

React, Vue, Next.js and other single-page apps

Load the script once in the root HTML document, not inside a component that re-renders. Route changes then keep the same widget and conversation, and the widget re-checks page rules as the address changes. If you must inject from code, guard against duplicates:

function loadSiteTrellis(siteId) {
  if (document.querySelector('script[data-site]')) return; // already loaded
  var s = document.createElement('script');
  s.src = 'https://cdn.sitetrellis.com/v/a44108d9c4521120/widget.js';
  s.async = true;
  s.setAttribute('data-site', siteId);
  document.body.appendChild(s);
}
loadSiteTrellis('site_XXXXXXXXXXXXXXXX');

Content Security Policy and Google Tag Manager

CSP. If your site sends a Content-Security-Policy header, allow the widget’s CDN host in script-src and the API host in connect-src; add an image host to img-src if your agent uses an avatar. If the widget renders unstyled, look for CSP violations about styles in the console. Test on staging first.

Tag Manager. Create a Custom HTML tag with the snippet, fire it once per page on All Pages or Window Loaded, and publish the container version. Do not trigger it on History Change, or it loads repeatedly. If you need consent first, require it in the tag’s consent settings or fire from a custom event your consent banner pushes. Some ad blockers block GTM itself, so a direct install is more resilient. The Tag Manager guide has the details. Use one install method per site.

The JavaScript API, in brief

The script defines window.SiteTrellis for opening the chat from your own buttons, sending a message, passing attributes and listening to events. Because the script is async, define a small queue stub before it so early calls are replayed:

<script>
  window.SiteTrellis = window.SiteTrellis || function () {
    (window.SiteTrellis.q = window.SiteTrellis.q || []).push(arguments);
  };
  SiteTrellis('setAttributes', { plan: 'pro' });
</script>
<script src="https://cdn.sitetrellis.com/v/a44108d9c4521120/widget.js" data-site="site_XXXXXXXXXXXXXXXX" async></script>

Attributes come from the browser and are not verified, so never use them to grant access or reveal private data. The full command and event list is in the Widget JavaScript API.

Why an install fails, quickly

Common installation problems on custom sites
SymptomCauseFix
Console says “missing or invalid data-site”The id has a typo or is truncated.Copy the snippet again.
CORS error or origin_not_allowedThe page origin is not listed, or www and non-www differ.Add the exact origin.
Works locally, not on the serverThe port or a file:// page sends an origin of null.Use a real local server and list its port.
Two launchersLoaded in the layout and again via GTM.Keep one method.
Script blockedCSP, an ad blocker or a corporate filter.Allow the hosts; test in a clean window.
Hidden, available is falseNo enabled, published agent.Publish an agent.

More in troubleshooting.

What to paste as knowledge for a custom or product site

Developer-built sites are often SaaS or documentation sites, so paste the facts a prospect or user needs: what the product does and does not do, plan limits, supported platforms, a short troubleshooting list and status page wording. The agent does not crawl your docs, so paste condensed text, and set a clear route to a person for account-specific problems. See chatbots for customer support and the BYOK overview.

Honest limits: no crawler or file upload, replies arrive whole, no native CRM connectors (use webhooks or an automation service), and no mobile SDK; the widget works in mobile browsers. The platform-specific routes are WordPress, Shopify, Wix and Squarespace; the integrations overview lists the rest.

Frequently asked questions

Does the chat widget work with React, Vue or Next.js?

Yes. Load the script once in the root HTML document rather than in a re-rendering component. If you inject it from code, check for an existing script tag first to avoid duplicates.

Can I install it through Google Tag Manager?

Yes, as a Custom HTML tag fired once per page. Use only one install method per site, and note that some ad blockers block GTM itself.

What do I need to change in my Content Security Policy?

Allow the widget’s CDN host in script-src and the API host in connect-src, and an image host in img-src if your agent uses an avatar. Test on a staging site first.

How do I open the chat from my own button?

Call SiteTrellis('open'). To pre-fill a question use SiteTrellis('sendMessage', text). Define the queue stub first so calls made before the async script loads are not lost.

Will the widget conflict with my site’s CSS?

No. It draws itself inside a Shadow DOM, which isolates it from your styles in both directions.

Why does it work on localhost but not in production?

Production origins must be in the allowed list, including www versus non-www and any subdomain. Add the exact origin of the live page.

One script, any stack

Start free, add the snippet to your layout and verify it in the Network tab. No credit card.

  • No credit card
  • Live in about 5 minutes
  • Your keys, your rules
Start free, no credit card