Skip to content
Public beta preview — you're seeing the sneak peek

Install the widget

read as .md

Your agent’s chat widget is one script tag. Every web service — a framework you build, a static generator, a CMS, a hosted site builder — has a place for code that runs on every page, right before </body>. The tag goes there once and the launcher appears on every page. The tag is the same everywhere; only where your site lets you put it differs.

Copy it from the console’s Embed tab (it renders with your real app id) or take it from here and put your app id in place of app_abc123 — the console shows it, and guuey apps list prints it:

<!-- guuey widget. Add this site to the app's allowed domains or the embed is refused. -->
<script src="https://widget.guuey.com/v1.js" data-app="app_abc123" async></script>

The loader reads data-app from its own tag and mounts; there is nothing else to write. When you want options — theme, launcher label, colours, position, a sign-in token endpoint — the console renders a two-script form instead (the bar layout is the one exception: the single tag carries it as data-layout="bar"); both forms are on Embed & share, and the loader is a permanent contract: paste once and it keeps working.

Find the one template that wraps every page of your site and put the tag just before </body>:

  • A framework you build (Next.js, Astro, Nuxt, SvelteKit, Vite/React, Rails, Laravel, Django…) — the root layout or base template.
  • A static generator (Jekyll, Hugo, Eleventy…) — the footer include or the default layout.
  • A CMS or hosted site builder (WordPress, Webflow, Squarespace, Framer, Shopify, Wix…) — the site-wide “custom code” / “code injection” setting, in its footer or end of body slot. The per-platform pages give the exact clicks as they land here.
  • A single-page app — once, in the root layout; the launcher follows route changes. To hide it on in-app routes, see Hiding the launcher on in-app routes.
  1. Allow your site’s origin. The widget is embeddable only on domains you’ve allowed: console → your app → EmbedAllowed origins, or guuey apps update <appId> --domains <origin>. A bare hostname (example.com) covers the apex and every subdomain; a scheme-prefixed origin (https://example.com) is an exact match. Changes take effect within about 15 seconds — reload your page after saving. Details: Allow your site’s domain.
  2. If your site sets a Content-Security-Policy, allow https://widget.guuey.com in frame-src and connect-src, and admit the tag and the loader’s one <style>: under a nonce-based policy put the page’s nonce on the tag (the loader carries it onto that <style>); under a host allowlist add https://widget.guuey.com to script-src and 'unsafe-inline' to style-src — nothing else. Why those: the CSP section.
  3. Verify with guuey apps check <appId> --origin <origin> — the same check the widget makes.

Give this to your coding agent (Claude Code, Codex, Cursor); it works out your stack and does the four steps above, asking only for what these pages already say. Copiable:

Paste into your coding agent
Install the Guuey chat widget on this site. Before changing anything, read
https://docs.guuey.com/install-widget.md and https://docs.guuey.com/embed.md
(the raw markdown of the two pages) and follow them exactly; do not invent
options or steps they do not contain.
1. Identify this site's stack and the one template or setting that wraps every
page (root layout, footer include, or the site-wide custom-code footer slot).
2. Put this tag there, just before </body>, with my app id <appId> in place of
app_abc123:
<script src="https://widget.guuey.com/v1.js" data-app="app_abc123" async></script>
Add nothing else to the tag — except your page's CSP nonce, if the site uses
nonces (step 4).
3. Tell me the exact origin(s) my pages are served from (scheme + host) so I can
add them to the app's allowed domains in the console (Embed → Allowed
origins) or with: guuey apps update <appId> --domains <origin>. Remind me that
a bare hostname covers the apex and every subdomain, while a scheme-prefixed
origin is an exact match, and that changes take about 15 seconds to apply.
4. If this site sets a Content-Security-Policy, add exactly these allowances and
nothing more. If the policy uses nonces (script-src 'nonce-...'): render the
site's per-request nonce on the widget tag the way its other script tags carry
it — that is what lets the loader run, and the loader puts the same nonce on the
one <style> it injects; then allow https://widget.guuey.com in frame-src and
connect-src. If the policy uses host allowlists: add https://widget.guuey.com to
script-src, frame-src and connect-src, and 'unsafe-inline' to style-src.
5. If this is a single-page app and the launcher should not show on in-app
routes, apply the hiding pattern from embed.md — otherwise leave it on every
page.
6. When I've saved the origin, verify with:
guuey apps check <appId> --origin <origin>
Stop and ask me before any step those two pages do not describe.

If you manage your site without a coding agent, the per-platform pages give the exact place, verified against the vendor’s own documentation and dated:

More land here as our visitors’ stacks ask for them. Until yours is listed, the rule is the same: the site-wide footer / end-of-body slot, one tag, then the three steps above.