Skip to content

Installation

There are three ways to load the widget: the plain script tag, manual init for single-page apps, and inline (embedded) mode.

Standard HTML sites

Drop the script tag anywhere on the page — just before </body> is a good spot:

html
<script
  src="https://cdn.lane.chat/js/widget.js"
  data-app-key="YOUR_APP_KEY"
></script>

data-app-key is equivalent to setting window.laneChatAppId before the script loads; its value is your application's app_pub. The widget auto-initializes on load.

App key attribute

The canonical attribute is data-app-key. If you see older snippets using data-app-id, prefer data-app-key — that is what the current widget reads.

Single-page apps (manual init)

In a SPA you usually want to control when the widget mounts and unmounts — for example, mount only on authenticated routes, or wait until you have the user's identity. Turn off auto-init and drive the lifecycle yourself:

html
<script>
  // Set BEFORE the widget script loads.
  window.laneChatManualInit = true
  window.laneChatAppId = 'YOUR_APP_KEY'
</script>
<script src="https://cdn.lane.chat/js/widget.js"></script>

Then mount and unmount as routes change:

js
// On route enter:
window.laneChat.init()

// On route leave:
window.laneChat.destroy()

init() is idempotent — calling it again reuses the existing instance rather than mounting a second widget. destroy() fully unmounts and is safe to init() again afterward.

Don't destroy just to push data

To update visitor data, call identify() — do not destroy() + init(). identify() updates in place without remounting or dropping the session.

React example

jsx
import { useEffect } from 'react'

export function SupportWidget() {
  useEffect(() => {
    // Ensure the loader is configured before the script runs. In practice you
    // set window.laneChatManualInit / window.laneChatAppId in index.html and
    // load the script once; here we just mount/unmount.
    window.laneChat?.init()
    return () => window.laneChat?.destroy()
  }, [])

  return null
}

Guard against the script not having loaded yet with window.laneChat?..

Inline (embedded) mode

Instead of a floating launcher, you can render the chat inline inside a container element you control. Set the mode and the container selector before the script loads:

html
<div id="support-panel" style="width: 380px; height: 600px;"></div>

<script>
  window.laneChatAppId = 'YOUR_APP_KEY'
  window.laneChatMode = 'inline'
  window.laneChatContainer = '#support-panel'
</script>
<script src="https://cdn.lane.chat/js/widget.js"></script>

You can also set these via script-tag attributes:

html
<script
  src="https://cdn.lane.chat/js/widget.js"
  data-app-key="YOUR_APP_KEY"
  data-mode="inline"
  data-container="#support-panel"
></script>

window.laneChatContainer must resolve to a DOM element. If it does not, the widget logs an error and falls back to floating mode.

Embedding the hosted host page directly

For webviews, iframes, or shared links you can point straight at the hosted host page instead of loading the script. Pass a url-encoded JSON object of visitor traits in data:

https://cdn.lane.chat/widget.html?app_id=app_xxx&layout=centered&data=%7B%22plan%22%3A%22pro%22%7D
  • layout=centered gives a responsive centered card (full-screen on phones); omit it for edge-to-edge fill.
  • user_id is folded into the data as external_user_id.
  • The JSON object in data becomes window.from_data inside the page and is shown to agents.

This is exactly how the native SDKs render chat.

Content Security Policy

If you run a CSP, allow the widget origin. The React runtime injects inline styles, so you also need style-src 'unsafe-inline' (or migrate to a nonce):

script-src 'self' 'unsafe-inline' https://cdn.lane.chat;
style-src  'self' 'unsafe-inline' https://cdn.lane.chat;
connect-src 'self' https://api.lane.chat https://cdn.lane.chat wss://dash.lane.chat;
img-src 'self' data: https:;

Adjust connect-src to match the API and WebSocket hosts your account uses.

Troubleshooting

  • Console warning Please set window.laneChatAppId or use data-app-key attribute — the widget could not read an app key. Check the <script> tag or your init order.
  • Widget doesn't appear after a deploy — the entry widget.js is served no-cache, but if you see a stale build, verify the response Last-Modified header and hard-refresh to rule out browser cache.

Lane.Chat — AI customer support, multichannel CRM, and roleplay AI.