---
title: "Install the widget"
description: "One script tag puts your agent's chat widget on any website — where the tag goes on every kind of site, what to allow first, and one prompt your coding agent can apply to any stack."
---

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.

## The tag

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:

<!-- prettier-ignore -->
```html
<!-- 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](/embed/#2-paste-the-snippet), and the loader is a permanent contract: paste once and it keeps working.

## Where it goes

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](/embed/#hiding-the-launcher-on-in-app-routes).

## Before it shows

1. **Allow your site's origin.** The widget is embeddable only on domains you've allowed: console → your app → **Embed** → **Allowed 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](/embed/#1-allow-your-sites-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](/embed/#if-your-site-sets-a-content-security-policy).
3. **Verify** with `guuey apps check <appId> --origin <origin>` — the same check the widget makes.

## One prompt for any stack

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:

```text title="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.
```

## Editing your site by hand?

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:

- [Plain HTML and static site builders](/embed/plain-html/)
- [Next.js](/embed/nextjs/)
- [WordPress](/embed/wordpress/)
- [Shopify](/embed/shopify/)
- [Wix](/embed/wix/)
- [Squarespace](/embed/squarespace/)
- [Webflow](/embed/webflow/)
- [Framer](/embed/framer/)
- [Vite single-page apps](/embed/vite/) (Create React App noted there)
- [Astro](/embed/astro/)
- [Jekyll](/embed/jekyll/)
- [Laravel](/embed/laravel/)

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.