Hopp til innholdet

DokumentasjonGuide for AI-agenterMarkdown

Implementing Snakkbar in a site — guide for AI agents

You are an agent with control over a website's code and want to add Snakkbar to it. Follow these steps in order. Every step ends with a check; do not move on until it passes.

0. Gather inputs

Ask the human for anything you cannot find yourself:

InputExampleWhere it comes from
SNAKKBAR_HOSThttps://www.snakkbar.appSnakkbar
TENANT_IDamatecSnakkbar (admin → Innstillinger)
SNAKKBAR_SECRET_KEYsk_snakkbar_…Only needed for steps 3 and 4. Admin → Innstillinger → API-nøkler. Store as a server secret.
Production origin(s)https://www.example.no, https://example.noThe site you control

Check: curl $SNAKKBAR_HOST/api/v1/tenants/$TENANT_ID/config returns JSON with the assistant's name.

Then decide, per side, how deep to integrate:

  • Visitor side: stock widget (default — choose this unless the human wants a custom chat design) or own UI with the SDK.
  • Staff side: hosted panel at $SNAKKBAR_HOST/panel (nothing to build), stock admin embedded in the site's own back office (step 3), or own UI with the SDK (step 5).

1. Allow the site's origins

The widget and embedded admin only work on allowed origins. As an admin in the Snakkbar admin (Innstillinger → Nettsteder som kan vise chatten) add every origin the site is served from. If you have an admin operator token, you can do it via the API:

bash
curl -X PATCH "$SNAKKBAR_HOST/api/v1/operator/tenant" \
  -H "authorization: Bearer $OPERATOR_TOKEN" -H "content-type: application/json" \
  -d '{"allowedOrigins":["https://www.example.no","https://example.no"],"siteHosts":["www.example.no","example.no"]}'

siteHosts are the hosts the assistant may read for answers (and where staff may send visitors).

Check: GET /operator/tenant lists the origins. (Local development on http://localhost:* works without this.)

2. Add the visitor widget

Add once, on every page, just before </body>:

html
<script src="https://<SNAKKBAR_HOST>/widget.js" data-tenant="<TENANT_ID>" defer></script>

Framework recipes:

  • Next.js (App Router) — in app/layout.tsx:
    tsx
    import Script from "next/script";
    // inside <body>:
    <Script src={`${process.env.NEXT_PUBLIC_SNAKKBAR_HOST}/widget.js`} data-tenant="<TENANT_ID>" strategy="afterInteractive" />
  • React SPA (Vite etc.) — put the tag in index.html.
  • Astro / SvelteKit / Nuxt — put the tag in the root layout's HTML.
  • WordPress — theme footer (footer.php) or a "header & footer scripts" plugin.
  • Content Security Policy — see widget.md.

Options and the JavaScript API (Snakkbar.open(), events, identified visitors) are in widget.md. Add a "Chat med oss" link anywhere with onclick="Snakkbar.open()".

Live visitors and consent. The widget also reports every visitor as a live visitor (pages, and the cursor while staff watch); this is on by default. Ask the human whether the site needs consent for this kind of tracking. If it has a consent banner, load the widget only after consent; if consent is needed but there is no banner, or they don't want it, turn it off with PATCH /api/v1/operator/tenant { "liveVisitors": false } (or Innstillinger in the admin). Details in widget.md.

Live view. For staff's «Se live» to show the real page, the site must allow being framed by the admin's origin: add frame-ancestors 'self' $SNAKKBAR_HOST (plus the origin of the site's own admin, if you do step 4) to the site's CSP, and remove any X-Frame-Options header. See admin-embed.md.

Check, in a real browser on the site:

  1. A round launcher appears bottom-right; no console errors.
  2. Clicking it opens the chat with the assistant's name and welcome text.
  3. Sending "Hei" streams an answer.
  4. The network tab shows no origin_not_allowed (403) responses.
  5. With live visitors on: POST /api/v1/visitor/activity goes out about every 10 s, and the visitor shows up in the admin under «Besøkende».

3. (Optional) Identified visitors

If the site has logged-in users, add a backend endpoint that returns a visitor token for the current user, and call Snakkbar.identify(fn) after login and Snakkbar.identify(null) on logout. Code in widget.md. Send the user's name, email, phone, company (and any attributes staff should see) with the token request; that is the trusted source. Where the page knows the user but you can't mint tokens, use Snakkbar.setUser({ ... }) or data-user-* instead (unverified, see widget.md).

Check: log in on two browsers as the same user; the chat history (☰ menu) is the same in both, and staff see the user's name on the visitor.

4. (Optional) Staff inbox inside the site's own admin

  1. Backend: an authenticated endpoint that exchanges the logged-in staff user for an operator token (POST $SNAKKBAR_HOST/api/v1/server/operator-tokens). Map your user id to externalId and your admin flag to role. Code in admin-embed.md.
  2. Admin page: a container with a fixed height, <script src="$SNAKKBAR_HOST/admin.js"> and Snakkbar.mountAdmin(container, { host, token }) where token fetches from your endpoint and caches until shortly before expiresAt. Code in admin-embed.md.
  3. The admin page's origin must be an allowed origin too (step 1).

Check:

  1. The inbox loads and shows the staff member's name (Innstillinger → Profil).
  2. Turn on Tilgjengelig; the widget launcher on the public site shows that person's face.
  3. From the public site, write "kan jeg snakke med et menneske?" — the inbox alerts «Spør etter deg»; join and reply; the visitor sees the reply live.
  4. Non-staff users get 401/403 from your token endpoint.

5. (Optional) Fully custom UI

Use the SDK instead of the stock UIs: sdk.md (visitor and staff clients, React hooks, rendering rules) and realtime.md. Follow the rendering rules in sdk.md so translations, product cards, suggestions, navigation and receipts behave like the stock UI. On a custom visitor UI, call client.startTracking() once per page load (on every page, so live visitors and the live view work) and client.updateProfile(...) when the user is known; respect the consent decision from step 2.

Check: the same scenario as step 4's checks works end to end with your UI.

6. Hand-over notes for the human

Tell the human:

  • where the widget tag lives in the code base and how to remove it;
  • the env vars you added (SNAKKBAR_HOST, SNAKKBAR_SECRET_KEY) and that the key must be rotated if it leaks;
  • which origins you allowed;
  • whether live visitors are on, and how consent is handled (or that liveVisitors is off), and whether you changed the site's CSP/X-Frame-Options for the live view;
  • that assistant behaviour (name, portrait, tone, instructions, welcome text, knowledge) is managed in the Snakkbar admin, not in the site's code.

Troubleshooting

SymptomCause / fix
Launcher never appearsScript blocked (CSP, ad blocker) or wrong data-tenant. Check console and the config request.
403 origin_not_allowedAdd the exact origin (scheme + host + port) to allowed origins.
Answers never arrive, but no errorA proxy buffers text/event-stream. Exclude /api/v1/* from buffering, or call Snakkbar directly (it is a different origin anyway).
401 unauthorized in the embedded adminToken endpoint returns an expired token; respect expiresAt.
Staff face never shows on the launcherStaff must be Tilgjengelig and have the admin open (heartbeats keep them online).
Widget looks off-brandSet the brand colour in the admin, or data-accent="#rrggbb".
No visitors under «Besøkende»liveVisitors is off, the widget is loaded only after consent that wasn't given, or (custom UI) startTracking() is never called.
«Se live» shows only a schematic pageThe site refuses framing: allow the admin's origin in frame-ancestors and drop X-Frame-Options.