Browse all docs

Install the widget

Install on any website (HTML)

Paste the SiteTrellis embed snippet before the closing body tag, set allowed origins, handle single-page apps and CSP, and verify the install.

Last updated:

The widget is one JavaScript file. It builds its own interface inside a Shadow DOM, so your site's CSS cannot break it and it cannot break your site's CSS. This page covers the plain-HTML install, which also applies to any framework or CMS that lets you edit the page template.

The snippet#

Copy your site's snippet from Sites in the dashboard. It looks like this, with your own public site id in place of the placeholder (a real id is site_ followed by 16 letters and digits; if the id is malformed the widget logs a warning in the console and does not start):

<script src="https://cdn.sitetrellis.com/v/a44108d9c4521120/widget.js" data-site="site_xxxxxxxx" async></script>
AttributeRequiredMeaning
srcYesThe widget script, served from the SiteTrellis CDN host.
data-siteYesYour site's public id. It is not a secret: it is visible to every visitor, which is why the allowed-origins list exists.
asyncRecommendedLoads the script without blocking your page rendering.
data-apiNoOverrides the API origin. By default the widget derives it from the script address (cdn. becomes api. in the host name). Only needed for local testing against a development instance or when you serve the script from a different host; leave it out in production.

Where to put it#

Put the tag on every page where the chat should be available, immediately before the closing </body> tag. In a site built from templates, that means your shared layout or footer file, so it is included once per page.

<!doctype html>
<html lang="en">
<head>
  <title>Example</title>
</head>
<body>
  <main>...</main>

  <!-- SiteTrellis chat widget -->
  <script src="https://cdn.sitetrellis.com/v/a44108d9c4521120/widget.js" data-site="site_xxxxxxxx" async></script>
</body>
</html>

Putting it in the <head> also works with async, but the end of the body is the safest place because it never competes with your page's own content for loading.

Include it once Loading the script twice on the same page (for example once in your layout and once through Google Tag Manager) can create two launchers or duplicate messages. Pick one method per site.

Allowed origins#

The API only talks to browsers on websites you have approved. In the dashboard, open your site and edit Allowed origins. An origin is the scheme, host and optional port, with no path and no trailing slash:

  • https://www.example.com
  • https://example.com (a different origin from the one above; add both if your site answers on both)
  • https://shop.example.com (every subdomain is its own origin)
  • https://*.example.com (a wildcard entry matches any subdomain, but not the bare example.com)
  • http://localhost:3000 (for development; the port matters)

An entry without a scheme, such as example.com, matches both http and https on the default port. Prefer the full form with https://, which is stricter.

While the list is empty the API accepts requests from any origin so you can get started quickly, and the dashboard flags the site as open. Before you launch, add your real origins. Requests from other origins are rejected, which prevents someone from embedding your site id on their own page to spend your AI budget.

Single-page apps#

With React, Vue, Next.js, Nuxt, Angular and similar frameworks, load the script once in the root HTML document (index.html, the root layout, or _document), not inside a component that re-renders. Route changes inside the app then keep the same widget and the same conversation.

If you must inject the script 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_xxxxxxxx');

To show the widget only on some pages, prefer the page rules (include and exclude URL patterns) in the widget settings over conditional script loading. See Widget customization. To pass information about the logged-in user or the current screen, see the JavaScript API.

Verify the install#

  1. Publish at least one agent on the site. Without a published agent the widget has nothing to offer and stays hidden.
  2. Load a page of your site and hard-refresh to bypass caches.
  3. Open your browser's developer tools and the Network tab. Filter for widget. You should see widget.js load with status 200, followed by a request to https://api.sitetrellis.com/v1/widget/config with status 200.
  4. If the config request is blocked with a CORS error, the page's origin is not on the allowed list.
  5. Click the launcher, send a message, and check that the conversation appears under Conversations.

As a shortcut, the site's page in the dashboard has a Check your installation section with a Run check button. It verifies that a published agent exists, reviews your allowed origins, and (if you entered the site's domain) fetches your page to look for the snippet. It cannot detect a snippet that a tag manager adds after the page loads, so for Google Tag Manager installs verify by chatting on the live site.

The config response includes an available flag. If it is false, there is no published agent for the site or the account is suspended.

Content Security Policy#

If your site sends a Content-Security-Policy header or meta tag, allow the SiteTrellis hosts or the widget will be blocked. Add the CDN host to script-src and the API host to connect-src:

Content-Security-Policy: script-src 'self' https://cdn.sitetrellis.com; connect-src 'self' https://api.sitetrellis.com

The two hosts shown are the ones used by this environment: the origin of the widget script URL and of the API URL. If your agent uses an avatar or launcher image, add that image's host to img-src. Because the widget applies its own styles inside the Shadow DOM, a strict style-src may also need adjusting; if the widget renders without styling, look for CSP violations in the browser console. Policies differ widely, so test in a staging environment first.

Caching and updates#

The widget script is cached by browsers and shared hosting layers like any static file. The widget configuration (colors, copy, behavior) is fetched separately and revalidated with an ETag, so settings changes appear for new page loads without any change to your page. If you use a performance plugin that combines, minifies or delays third-party scripts, exclude the SiteTrellis script from it; see Troubleshooting.

Platform guides WordPress, Shopify, Wix, Squarespace and Google Tag Manager each have their own page.