Install guide
Installing a chat assistant in a Vue project
A Vue app built on Vite has exactly one HTML file, and the tag goes at the end of its body. Two Vue behaviours catch people out on the way there: the template compiler quietly drops script tags, and mounting the app empties the element it mounts into.
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 Vue
index.html at the project root, after the div the app mounts into and immediately before the closing body tag.
Any Vue application you build and serve yourself. You own index.html, so nothing needs unlocking. Vue projects rendered by a meta framework belong on that framework's page.
Step by step
- 1Open index.html at the project root. It sits beside package.json, not inside src and not inside public.
- 2Find the div with the app id, and the module script below it that imports your entry file.
- 3Paste the tag on its own line after that script and immediately before the closing body tag.
- 4Save. Vite serves index.html on every request in development, so a reload is usually enough and a restart is not needed.
- 5Open the app and confirm the launcher appears in the corner.
- 6Allowlist the development origin as well as production, since the browser treats the local port as an origin of its own.
What goes wrong on Vue
The template compiler ignores script tags
Writing the tag inside a component template does not work. Vue treats script and style tags in a template as side effecting markup and drops them, warning that tags with side effects are ignored in component templates. That is a compile time warning in a busy terminal rather than a runtime error, so it is easy to scroll past.
The template is not the shell. index.html is.
Mounting empties the app element
Calling mount replaces the contents of the element you point it at. Anything pasted inside the div with the app id is gone the moment the app boots, with no warning at all.
Put the tag after that div, never inside it.
Route changes are not page loads, which is the point
Vue Router in history mode never leaves the document. It swaps components and rewrites the URL. The loader installs once when the page first loads and stays installed for every route the visitor walks through afterwards, which is why there is nothing to hook into on navigation. Hash mode behaves the same way.
If the widget does seem to vanish on a route change, something in your own code removed the element, or something called the destroy method on the global.
Origins to allowlist
These are the origins a Vue 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://app.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.
| One tag, nothing else | There is no second file, no stylesheet and no package to install. The tag is the whole install. |
|---|---|
| Where it goes | Immediately 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 required | Without it the loader stops and writes a warning to the browser console rather than rendering anything. |
| It finds itself | The 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 once | A 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 tag | Everything 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 late | Only 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 collide | The 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 redeploy. There is nothing else to undo, because the tag is the whole install.
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
- Can I add it from a component instead?
- You can create the element with document.createElement in a mounted hook and call the destroy method on the global when the component is unmounted. There is rarely a reason to. The only real case is wanting the widget on some routes and not others.
- Should I use a head management plugin for this?
- Only if you already run one for other reasons. This tag never changes and never depends on the current route, so declaring it once in index.html is less machinery for the same result.
- The tag is in index.html but no launcher appears. What now?
- Check two things in order. View source on the served page to confirm the tag sits outside the div the app mounts into, then read the console for a refused origin, which names the origin the allowlist rejected.
- What should a Vue app index for the assistant to read?
- Whatever a visitor would read: your documentation, pricing and policy pages. It answers only from material you index, cites what it used, and says it does not know rather than inventing an answer.
Keep reading
- Install on Next.jsapp/layout.tsx in the App Router, or pages/_document.tsx in the Pages Router. Not a client component that can unmount.
- Install on Reactindex.html at the project root for a Vite app, or public/index.html for Create React App. Immediately before the closing body tag.
- Install on Nuxtnuxt.config.ts, under app, then head, then the script array. Or a useHead call in layouts/default.vue.
- Every install guideThe same one line of HTML, and where it goes on each platform.
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.