# Install the chat widget

> Add the Giov chat to any website with one script tag, then approve your domain and check the connection.

The widget is one script. It loads asynchronously, so it doesn't block your page, and it renders inside its own shadow DOM, so your site's CSS and the chat's CSS don't affect each other.

## Find your workspace ID

Open **Settings → Chat widget → Installation** and choose **Manual**. Your workspace ID is shown below the snippet, with a copy button. The snippets in the dashboard already include it.

When you're signed in, the examples on this page already use your workspace ID. Otherwise, swap in the ID you copied from the dashboard.

## Add the script

Load the widget once per page. On a plain website, place the tag just before the closing `</body>` tag. In a framework, put the component in your root layout (`App`, `app/layout.tsx`, `+layout.svelte` or `App.vue`) and render it once.

```html title="index.html" tab="HTML"
<script src="https://widget.giovchat.app/YOUR_WORKSPACE_ID" async></script>
```

```tsx title="GiovWidget.tsx" tab="React"
import { useEffect } from "react";

export function GiovWidget() {
  useEffect(() => {
    if (document.getElementById("giovchat-widget")) return;

    const script = document.createElement("script");
    script.id = "giovchat-widget";
    script.src = "https://widget.giovchat.app/YOUR_WORKSPACE_ID";
    script.async = true;
    document.body.appendChild(script);

    return () => script.remove();
  }, []);

  return null;
}
```

```tsx title="app/giov-widget.tsx" tab="Next.js"
"use client";

import { useEffect } from "react";

export function GiovWidget() {
  useEffect(() => {
    if (document.getElementById("giovchat-widget")) return;

    const script = document.createElement("script");
    script.id = "giovchat-widget";
    script.src = "https://widget.giovchat.app/YOUR_WORKSPACE_ID";
    script.async = true;
    document.body.appendChild(script);

    return () => script.remove();
  }, []);

  return null;
}
```

```svelte title="GiovWidget.svelte" tab="Svelte"
<script lang="ts">
  import { onMount } from "svelte";

  onMount(() => {
    if (document.getElementById("giovchat-widget")) return;

    const script = document.createElement("script");
    script.id = "giovchat-widget";
    script.src = "https://widget.giovchat.app/YOUR_WORKSPACE_ID";
    script.async = true;
    document.body.appendChild(script);

    return () => script.remove();
  });
</script>
```

```vue title="GiovWidget.vue" tab="Vue"
<script setup lang="ts">
import { onBeforeUnmount, onMounted } from "vue";

let script: HTMLScriptElement | undefined;

onMounted(() => {
  if (document.getElementById("giovchat-widget")) return;

  script = document.createElement("script");
  script.id = "giovchat-widget";
  script.src = "https://widget.giovchat.app/YOUR_WORKSPACE_ID";
  script.async = true;
  document.body.appendChild(script);
});

onBeforeUnmount(() => script?.remove());
</script>
```

```html title="Footer code" tab="WordPress"
<!-- Add with a footer or code-injection plugin -->
<script src="https://widget.giovchat.app/YOUR_WORKSPACE_ID" async></script>
```

On WordPress, use a footer or code-snippet plugin and place the tag once, before the closing body tag.

> [!NOTE]
> The loader runs only in the top-level page. If your page is shown inside an iframe, add the script to the parent page, or use the [iframe embed](/docs/widget/csp#iframe-embed).

### Install with a coding agent

**Settings → Chat widget → Installation → Agent assisted** gives you a project-aware prompt for Codex, Claude Code, Cursor or another coding agent. Select **Copy installation prompt** and paste it into your agent. Your workspace ID is already included. The prompt asks the agent to load the widget once from your root layout, run your build, and report the files it changed.

## Approve your domain

Register the websites allowed to embed your chat in **Settings → Chat widget → Authorizations**:

1. Set **Type** to **Website URL**.
2. Enter the site in **Value**, for example `https://example.com`.
3. Select **Register**.

| Your list | Where the chat loads |
|---|---|
| No websites registered | On any website. |
| One or more websites | Only on those hosts and their subdomains. Registering `example.com` also covers `www.example.com` and `shop.example.com`. |

> [!WARNING]
> Once you register a website, every other host is blocked, including staging sites and `localhost`. Register each host you use.

A website can be registered by only one workspace. If someone else already registered it, you'll see "This URL or ID is already registered by another account."

## Check the installation

1. **Test connection.** In **Settings → Chat widget → Installation**, the **Connection check** section confirms that your workspace's public widget configuration is reachable. It doesn't inspect your website.
2. **Open your site.** The launcher appears in the bottom-right corner by default. Send a test message and look for it in **Inbox**.

During onboarding, the **Install** step also detects the first time the chat loads on your site and shows **Seen on** with the host.

If the widget's stylesheet or configuration can't load, the widget removes itself instead of showing an unstyled chat.

## Troubleshooting

| Symptom | Likely cause |
|---|---|
| No launcher on any page | The workspace ID is wrong, or your Content Security Policy blocks Giov. See [Content Security Policy](/docs/widget/csp). |
| Works on your live site but not on staging or `localhost` | That host isn't registered under **Authorizations**. |
| No launcher on a page shown inside an iframe | The loader skips iframes. Add it to the parent page. |
| The script is included twice | The second copy does nothing, but keep one copy to avoid extra requests. |
| The launcher stopped loading everywhere at once | Check [System status](/status) for a Website widget incident. |

## Next

- [Customize the widget](/docs/widget/customize)
- [Identify signed-in visitors](/docs/widget/identify-visitors)
- [JavaScript API](/docs/widget/javascript-api)
- Native apps: [Mobile apps](/docs/mobile)
