Install guide
Installing a chat assistant in a Nuxt project
Nuxt generates the document rather than serving one you wrote, so the tag is declared in configuration and arrives in the server rendered HTML. That is tidier than it sounds. The catches are where the tag lands by default, and what happens when the component that registered it goes away.
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 Nuxt
nuxt.config.ts, under app, then head, then the script array. Or a useHead call in layouts/default.vue.
Any Nuxt project. There is no HTML file to edit because Nuxt builds the document, so the configuration is the shell and you always control it.
Step by step
- 1Open nuxt.config.ts at the project root.
- 2Under the app key add a head object, and inside it a script array.
- 3Add one entry to that array: src set to the loader URL, defer set to true, and the data-key attribute set to your publishable key. Attribute names containing a hyphen have to be written as quoted keys in the object.
- 4Add tagPosition set to bodyClose on the same entry if you want it at the end of the body rather than in the head. Either position works, because the tag defers.
- 5Restart the development server. nuxt.config is read at startup and changes to it are not hot reloaded.
- 6Load a page and view source. The tag is in the delivered HTML rather than added later, which makes it easy to confirm the key came through intact.
- 7Allowlist the development origin and the production origin, which are never the same origin.
What goes wrong on Nuxt
useHead in a page removes the tag when the page unmounts
useHead registers tags on behalf of the component that called it, and Nuxt removes them again when that component goes away. Call it in a page component and the tag disappears from the document as soon as the visitor navigates elsewhere.
The loader has already installed itself by then, so the widget keeps working and you are left with a document that does not match your code. Register it in nuxt.config, or in a layout that stays mounted for the whole session.
The script array defaults to the head
Entries in the head script array go into the head unless you name a position with tagPosition. That is harmless for this tag, which defers, and whose loader waits for the document to be ready regardless.
It is still worth setting bodyClose explicitly, so the next person reading the config does not have to know the default to know where the tag ends up.
Registering it twice does not give you two tags
Nuxt deduplicates head entries, so the same src declared in nuxt.config and again through useHead collapses into a single tag rather than two. Convenient, and also a good way to confuse yourself during removal.
You delete the config entry, the widget still loads, and you conclude the config was never doing anything. Search the whole project for the loader URL when you are trying to take it off.
Origins to allowlist
These are the origins a Nuxt site is typically served from. List every one you want the assistant to answer on, including the ones only you visit.
- http://localhost:3000
- 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.
| 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. |
Set up on Nuxt for a particular trade
The tag is the same everywhere. What is not the same is which of your pages the assistant can read once it is running, and on Nuxt that depends on what kind of site this is. These go one level further than this guide.
Taking it off again
Delete the entry from the script array in nuxt.config, and remove any useHead call that registers the same src. Rebuild, because the tag is baked into the rendered HTML.
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
- nuxt.config or useHead?
- nuxt.config for a tag that belongs on every page, which this one does. useHead is for head content that depends on the current route, and a widget that installs once per document is not that.
- Does it run during server rendering?
- No. The tag is emitted as markup on the server and everything the loader does happens in the browser, so there is no window access during the render and nothing to guard against.
- Does server rendering change anything about the widget?
- Only where the tag comes from. It arrives in the HTML rather than being appended by client code, so the loader can start marginally sooner. Its behaviour after that is identical.
- Do I need a module for this?
- No. It is one script tag and Nuxt already has a supported place to declare one. A module would be a wrapper around a single line of configuration.
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 Vueindex.html at the project root, after the div the app mounts into and immediately before the closing body tag.
- 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.