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

# Troubleshoot the widget

> Symptom-first fixes for a missing button, a chat that won't open, stale sessions, styling that doesn't apply, and voice problems

Start with three checks in the browser. `window.LuaPop.config` prints the merged configuration the widget is using; the value `init()` resolves to is `null` when nothing was mounted; and the **Network** tab shows the two requests that run right after `init()`: the settings lookup (`/webchat/config`) and the end user sign-in (`auth.heylua.ai/agent/<agentId>`).

```js theme={null}
const widget = await window.LuaPop.init({ agentId: "agent_abc123", environment: "production" });
console.log(widget !== null, window.LuaPop.config);
```

## Loading

### `init()` resolves to `null` and nothing renders

**Cause** — You called `window.LuaPop.init()` with no options on a domain that has no admin dashboard settings: the domain is not under **Allowed websites**, or it is a development host (`localhost`, `127.0.0.1`, private IP addresses, and hosts ending in `.local`, `.localhost`, `.test`, `.example`, or `.invalid`), where admin dashboard settings never load. The path can also match `excludedPaths`.

**Fix** — Add the domain in the admin dashboard, or pass at least `agentId` and `environment: "production"` inline.

### The button appears but the chat never answers, and requests go to `api.lua.dev`

**Cause** — You passed inline options without `environment`, and no admin dashboard settings were found for the domain. The widget's built-in fallback is `"staging"`, Lua's internal platform, where your agent does not exist.

**Fix** — Add `environment: "production"` to every `init()` call that passes options.

### `LuaPop: Invalid environment value "…"`

**Cause** — `environment` is something other than `"production"`, `"custom"`, or `"staging"`. The widget logs this and uses `"staging"`.

**Fix** — Use `"production"`.

### Nothing appears and the console is empty

**Cause** — The widget renders only after its stylesheet, `https://lua-ai-global.github.io/lua-pop/style.css`, has loaded; a content security policy or a blocker that stops it leaves the page empty. Another script may also have removed the `#lua-shadow-root` element or called `window.LuaPop.destroy()`.

**Fix** — Allow `lua-ai-global.github.io` in `script-src` and `style-src`, confirm the stylesheet loads in the **Network** tab, and place both script tags right before `</body>`.

## Conversation

### `LuaPop widget authentication error`

**Cause** — The end user sign-in failed: the agent ID is wrong or the agent is not live in production, or the session ID stored in the browser was rejected.

**Fix** — Check `window.LuaPop.config.agentId`, then clear the stored session ID and reload.

```js theme={null}
localStorage.removeItem("lua_pop_session_id");
```

### Every page load starts a new conversation

**Cause** — The `sessionId` you pass changes between loads, or you pass `authToken` on an agent without a custom sign-in: the widget then sends no session ID and the sign-in creates a fresh anonymous identity each time.

**Fix** — Pass a value that is stable per end user, or omit `sessionId` and let the widget store one in `localStorage`; remove `authToken`.

### `LuaPop: Target container with id "…" not found`

**Cause** — In embedded mode, `embeddedDisplayConfig.targetContainerId` names an element that is not in the DOM when `init()` runs. A missing `targetContainerId` logs `LuaPop: embeddedDisplayConfig.targetContainerId is required when displayMode is 'embedded'` instead.

**Fix** — Render the container first, then call `init()`. Give the container an explicit height, or set `useContainerHeight: true` in a flexible layout.

## Appearance

### My CSS doesn't reach the widget

**Cause** — The widget renders inside an open shadow root on `#lua-shadow-root` (`#lua-shadow-root-embedded` when embedded), and page stylesheets stop at that boundary.

**Fix** — Use the style options, or append a `<style>` element to the shadow root after `init()` resolves; see [Style the widget](/channels/web-widget/styling).

### The button is not in the corner I configured

**Cause** — With `draggable: true`, the spot an end user dragged the button to is stored in their browser under the `localStorage` key `luapop:pos:<agentId>` and wins over `position`.

**Fix** — Remove that key to reset, or turn `draggable` off.

## Voice

### The voice window shows Connection Error

**Cause** — The end user denied microphone access, the page is not a secure context, or the live connection failed.

**Fix** — Serve the page over HTTPS and have the end user allow the microphone in the browser's site settings, then try again. Text chat keeps working meanwhile.

## Migrating from another widget

<Accordion title="Option mapping from Intercom, Zendesk, and Drift">
  | Purpose                  | Other widgets                                     | Lua widget                                                                              |
  | ------------------------ | ------------------------------------------------- | --------------------------------------------------------------------------------------- |
  | Identify the end user    | Intercom `user_id`, Drift `userId`                | `sessionId`, one stable value per end user                                              |
  | Brand color              | Zendesk `color.theme`, Drift `theme.primaryColor` | `buttonColor`                                                                           |
  | Launcher text            | Drift `teaser.text`                               | `buttonText`                                                                            |
  | Open and close callbacks | Intercom `onShow`, Zendesk `webWidget:on open`    | `widget_opened` and `widget_closed` [events](/channels/web-widget/events-and-analytics) |

  Remove the old snippet before adding the Lua script.
</Accordion>

## Still stuck

Write to [support@heylua.ai](mailto:support@heylua.ai) with the page URL, the `init()` call, the output of `window.LuaPop.config`, and any console errors.
