Docs

Install OpenMate

One script tag adds the assistant to your website. It works on any stack — pick your platform below and copy the snippet.

Code
<script src="https://api.openmate.bond/widget.js" data-bot-id="YOUR_BOT_ID" defer></script>

Paste your own data-bot-id where it says YOUR_BOT_ID.

In four steps

  1. 1

    Create your assistant

    Sign up and copy your bot id — the public identifier you paste into the tag.

  2. 2

    Register your website origin

    Add your exact site origin (for example https://acme.com) in the dashboard’s Origins page. Without it, the widget refuses to load.

  3. 3

    Paste the script tag

    Add the tag to your site using the guide for your stack below. One tag, once.

  4. 4

    Check it loads

    Open your site, look for the chat button bottom-right, and ask it a question.

Choose your platform

The install is the same tag in every case — only the file changes.

Plain HTML / CSS / JavaScript

Paste the tag before the closing </body> tag on every page (or in your shared layout/footer).

Code
<!DOCTYPE html><html>  <body>    <!-- your page content -->    <script      src="https://api.openmate.bond/widget.js"      data-bot-id="YOUR_BOT_ID"      defer    ></script>  </body></html>

No build step, no framework. If your site has a shared footer file, add it there once and every page gets it.

React (Vite / CRA / plain)

Add it once to the public index.html — Vite and CRA both serve this file unchanged.

Code
<!-- index.html (Vite) or public/index.html (CRA) --><body>  <div id="root"></div>  <script    src="https://api.openmate.bond/widget.js"    data-bot-id="YOUR_BOT_ID"    defer  ></script></body>

Keep it outside <div id="root">: React only manages its own root, so the widget is never touched by re-renders.

React — inject at runtime

No HTML file to edit? Load the script from a top-level component with an effect.

Code
import { useEffect } from 'react';export default function OpenMateWidget() {  useEffect(() => {    const s = document.createElement('script');    s.src = 'https://api.openmate.bond/widget.js';    s.setAttribute('data-bot-id', 'YOUR_BOT_ID');    s.defer = true;    document.body.appendChild(s);    return () => s.remove();  }, []);  return null;}

Render <OpenMateWidget /> once in App. The cleanup removes the tag on unmount so a hot reload cannot mount two.

Next.js (App Router)

Use next/script in the root layout so it loads once for the whole app.

Code
// app/layout.jsimport Script from 'next/script';export default function RootLayout({ children }) {  return (    <html lang="en">      <body>        {children}        <Script          src="https://api.openmate.bond/widget.js"          data-bot-id="YOUR_BOT_ID"          strategy="afterInteractive"        />      </body>    </html>  );}

strategy="afterInteractive" keeps the site fast: the widget loads after the page is usable.

Next.js (Pages Router)

Put it in _app.js so it appears on every route.

Code
// pages/_app.jsimport Script from 'next/script';export default function App({ Component, pageProps }) {  return (    <>      <Component {...pageProps} />      <Script        src="https://api.openmate.bond/widget.js"        data-bot-id="YOUR_BOT_ID"        strategy="afterInteractive"      />    </>  );}

Vue (Vite / Vue CLI)

Add it to index.html — the Vue app mounts into #app, so the tag sits alongside it.

Code
<!-- index.html --><body>  <div id="app"></div>  <script    src="https://api.openmate.bond/widget.js"    data-bot-id="YOUR_BOT_ID"    defer  ></script>  <script type="module" src="/src/main.js"></script></body>

For Nuxt, put the same tag in nuxt.config or app.html.

Angular

Add the tag to src/index.html. Angular only manages <app-root>.

Code
<!-- src/index.html --><body>  <app-root></app-root>  <script    src="https://api.openmate.bond/widget.js"    data-bot-id="YOUR_BOT_ID"    defer  ></script></body>

The widget needs no Angular module. If your CSP is strict, allow the script origin (see the checklist below).

Troubleshooting

Nothing appears on the page
Check the browser console. “ORIGIN_NOT_ALLOWED” means your site’s origin is not registered — add it in the dashboard’s Origins page. The origin must match exactly (scheme + host + optional port, no trailing slash).
Blocked by a Content-Security-Policy
Allow your OpenMate host in script-src and frame-src. The widget mounts a sandboxed iframe, so the frame origin must be allowed too.
It loaded once but disappeared
A single-page-app re-render replaced the DOM. Load the script once from an HTML file or a root layout (as the guides above do), not inside a component that unmounts.

Ready to add your bot id?

Create an assistant to get your bot id, then register the site you will embed it on.

Create your assistant