Install guide

Installing a chat assistant in a React app built with Vite or Create React App

A React app you build yourself ships one HTML file and mounts into it. That file is where the tag goes. This page exists for the failure almost everybody hits first: a script element written in JSX looks correct, renders without complaint, and does absolutely nothing.

The tag

<script src="https://cdn.askably.xyz/w.js" data-key="pk_live_YOUR_KEY" defer></script>

Your own key replaces the placeholder. You will find it on the install tab of the assistant.

The origin the page is served from has to be on the allowlist for that assistant, or nothing renders and the browser console says which origin was refused. An apex domain and its www are two different origins to a browser, so list both, along with any staging or preview host you want it to work on.

Where it goes on React

index.html at the project root for a Vite app, or public/index.html for Create React App. Immediately before the closing body tag.

Any React app where you own the HTML shell, which is every app you build with a bundler yourself. React projects where a meta framework generates the document are covered on that framework's page instead.

Step by step

  1. 1Open index.html at the project root if you are on Vite, or public/index.html if you are on Create React App.
  2. 2Scroll past the div React mounts into, and past the script that boots the application.
  3. 3Paste the tag on its own line immediately before the closing body tag, with your publishable key in the data-key attribute.
  4. 4Save and restart the development server so the shell is served again.
  5. 5Load the app and confirm the launcher appears once the page settles.
  6. 6Allowlist the local development origin as well as both production origins, or it will only ever appear in one of the two places.

What goes wrong on React

A script element written in JSX never runs

This is the one that wastes the most time, because nothing goes wrong loudly. React puts the element into the page by setting markup rather than by parsing a document, and browsers deliberately refuse to execute script elements inserted that way. Inspect the DOM and the element is there with the right src. Watch the network panel and no request for it is ever made. There is no console error to search for.

If you genuinely need to add it at runtime, build the element with document.createElement, set src, defer and the data-key attribute on it, append it to the body, and call the destroy method on the global when the component unmounts.

Mounting clears whatever is inside the root element

React replaces the contents of the element you hand to createRoot. A tag pasted inside that div is discarded the instant the app mounts, silently and with nothing in the console.

Keep it outside, after the closing div and immediately before the closing body tag.

Editing the built copy instead of the source

Vite copies index.html into dist during a build, and Create React App copies public/index.html into build. Pasting the tag into the built copy works locally until the next build overwrites it, and since deployments usually run a fresh build, the change never reaches production.

Check that the file you edited is the one under version control.

Origins to allowlist

These are the origins a React site is typically served from. List every one you want the assistant to answer on, including the ones only you visit.

  • http://localhost:5173
  • https://yourdomain.com
  • https://www.yourdomain.com

How the tag behaves, wherever you put it

The rest of this is the same on every platform, so it is worth reading once rather than on each guide.

Loader behaviour
One tag, nothing elseThere is no second file, no stylesheet and no package to install. The tag is the whole install.
Where it goesImmediately before the closing body tag. It works in the head too, because it defers, but the body keeps it out of the way of anything that measures render order.
data-key is requiredWithout it the loader stops and writes a warning to the browser console rather than rendering anything.
It finds itselfThe loader reads the tag it was loaded from, and falls back to the first tag on the page carrying a data-key. Platforms that move or re-inject the tag do not break it.
It installs onceA second copy of the tag on the same page is ignored, so a template that renders twice does not produce two launchers.
Assets follow the tagEverything else it needs is fetched from the same origin the tag was served from, so a proxy or a private domain needs no extra configuration.
The panel loads lateOnly the small launcher is on the page at first. The conversation panel is fetched the first time a visitor opens it, in its own frame.
Styles cannot collideThe launcher renders inside a closed shadow root and the panel inside a frame, so nothing on the host page can restyle either, and neither can restyle the host page.

Taking it off again

Delete the line from index.html and rebuild. If you added it at runtime instead, call the destroy method on the global and remove the code that created the element.

Before you remove it

  • Removing the tag stops the widget on that site. It does not delete the assistant, its material, or the enquiries it has already collected.
  • If you are moving the widget to a different host rather than retiring it, add the new origin to the allowlist before you remove the old tag, or there is a window where neither works.

Questions

Why does nothing happen when I render the script tag from a component?
Because React inserts it as markup, and a browser will not execute a script element inserted that way. No error is raised, which is why it feels like the key or the URL must be wrong when neither is. Put the tag in index.html instead.
Do I need to remove it when a component unmounts?
Not if the tag is in index.html, because no component owns it. If you injected it at runtime from a component, call the destroy method on the global in your cleanup so the launcher and its frame go away with the component.
Does it need reinstalling when the route changes?
No. A single page app is one document, so the loader installs once on the first load and stays for every screen the visitor moves through afterwards.
Vite or Create React App, is the file different?
Only the path. Vite keeps index.html at the project root, Create React App keeps it in public. In both, the tag goes immediately before the closing body tag.

Keep reading

Try it on your own material

Upload a document or point it at your site, paste one line of HTML, then ask it something only your business could answer.