> ## Documentation Index
> Fetch the complete documentation index at: https://docs.callkaro.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Installing on Your Website

> Add the widget snippet to any website, framework or CMS

## Overview

Installation is a single script tag. Paste it just before the closing
`</body>` tag of any page where the widget should appear.

```html theme={null}
<script src="https://widget.callkaro.ai/w.js" data-ck-id="your-widget-id" defer></script>
```

Replace `your-widget-id` with the id from your dashboard. That is the entire
integration — no API key, no npm package, no backend endpoint to build.

<Tip>
  Put it in your site's shared layout, header or footer template so it applies to
  every page at once, rather than pasting it page by page.
</Tip>

***

## Plain HTML

```html theme={null}
<!doctype html>
<html>
  <body>
    <!-- your page -->

    <script src="https://widget.callkaro.ai/w.js" data-ck-id="your-widget-id" defer></script>
  </body>
</html>
```

***

## React

React strips a plain `<script src>` written in JSX, so it never runs. Inject the
tag once on mount instead:

```jsx theme={null}
import { useEffect } from "react"

export default function CallKaroWidget() {
  useEffect(() => {
    const s = document.createElement("script")
    s.src = "https://widget.callkaro.ai/w.js"
    s.defer = true
    s.dataset.ckId = "your-widget-id"
    document.body.appendChild(s)
    return () => s.remove()
  }, [])

  return null
}
```

Render `<CallKaroWidget />` once in your top-level layout.

***

## Next.js

### App Router

Add it to your root layout using `next/script`:

```tsx theme={null}
import Script from "next/script"

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}

        <Script
          src="https://widget.callkaro.ai/w.js"
          data-ck-id="your-widget-id"
          strategy="afterInteractive"
        />
      </body>
    </html>
  )
}
```

### Pages Router

The same `<Script>` goes in `pages/_app.tsx`, or in `pages/_document.tsx` just
before `</body>`.

<Note>
  Use `next/script` rather than a raw `<script>` tag — React does not execute
  script tags written directly in JSX. Do not add `defer` alongside
  `strategy`; the strategy already controls load timing.
</Note>

***

## WordPress

<Steps>
  <Step title="Open the theme file editor">
    Go to **Appearance → Theme File Editor** and open `footer.php`.
  </Step>

  <Step title="Paste the snippet">
    Add it immediately before `</body>`.
  </Step>

  <Step title="Update the file">
    Click **Update File**, then load your site to confirm the launcher appears.
  </Step>
</Steps>

<Tip>
  Editing theme files directly means your change is lost on the next theme
  update. A "header and footer scripts" plugin, or a child theme, is safer.
</Tip>

***

## Shopify

<Steps>
  <Step title="Open the code editor">
    Go to **Online Store → Themes → ⋯ → Edit code**.
  </Step>

  <Step title="Open theme.liquid">
    Find it under the **Layout** folder.
  </Step>

  <Step title="Paste before the closing body tag">
    Add the snippet just above `</body>` and save.
  </Step>
</Steps>

***

## Webflow

<Steps>
  <Step title="Open site settings">
    Go to **Project Settings → Custom Code**.
  </Step>

  <Step title="Add to Footer Code">
    Paste the snippet into the **Footer Code** box.
  </Step>

  <Step title="Publish">
    Save, then publish your site. Custom code only runs on the published site,
    not in the Webflow designer.
  </Step>
</Steps>

***

## Google Tag Manager

<Steps>
  <Step title="Create a new tag">
    In your GTM workspace, create a tag of type **Custom HTML**.
  </Step>

  <Step title="Paste the snippet">
    Add the script tag exactly as given.
  </Step>

  <Step title="Set the trigger">
    Use **All Pages**, or a narrower trigger if you only want the widget on
    certain pages.
  </Step>

  <Step title="Publish">
    Submit and publish the container.
  </Step>
</Steps>

***

## Verifying The Installation

<Steps>
  <Step title="Load your site">
    The launcher should appear in the corner you configured, in your primary
    colour and with your icon.
  </Step>

  <Step title="Open the widget">
    Click the launcher. The header should show your bot name and the agent's
    name, with a **Ready** status.
  </Step>

  <Step title="Start a conversation">
    Press **Talk**. Your browser asks for microphone permission, the status
    changes to **Live**, and the transcript appears as you speak.
  </Step>
</Steps>

If any step fails, see [Troubleshooting](/widget/troubleshooting).

***

## Content Security Policy

If your site sends a `Content-Security-Policy` header, the widget's origins need
to be allowed or the browser will block it silently:

```
script-src  https://widget.callkaro.ai;
frame-src   https://widget.callkaro.ai;
connect-src https://backend.callkaro.ai;
```

<Warning>
  Also make sure your site does not send a restrictive `Permissions-Policy` for
  `microphone`. The widget delegates microphone access to its own iframe, and a
  policy such as `microphone=()` blocks that delegation — the widget will load
  correctly but conversations will fail to start.
</Warning>

***

## Multiple Widgets On One Site

Only one widget can run per page. If two snippets end up on the same page — a
common accident when it is added to both a layout and an individual template —
the second is ignored rather than producing two launchers.

To use different agents on different sections of your site, install different
widget ids on different pages instead of on a shared layout.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Customization" icon="palette" href="/widget/customization">
    Change appearance without touching your site again
  </Card>

  <Card title="JavaScript API" icon="code" href="/widget/javascript-api">
    Open the widget from your own buttons and track events
  </Card>
</CardGroup>
