Skip to navigation

Embedding the chat widget (script tag)

Use the script-tag embed to add the Runtype chat widget to an HTML page without installing a framework package. For React apps, see Embedding the chat widget (React).

Before you begin

Complete the following prerequisites before you get the embed code:

  • Create a Product with a chat Surface. For more information, see Setting up a chat surface.
  • Link at least one Capability to the Surface.
  • Create a client token and add your website origin to Allowed Origins.

Get the embed code

Copy the snippet from the workbench or the classic dashboard. The snippet includes the client token and your saved widget settings.

In the workbench

To copy the snippet in the workbench, follow these steps:

  1. Open the chat Surface and select Embed.
  2. Select Script tag.
  3. In the token menu, select a client token, or select Create token… to create one.
  4. If you selected a live token, paste the token value that you saved when you created it into Saved live token. Runtype stores only a hint of a live token, so the workbench can’t fill in the value for you.
  5. Click Copy.

Copy stays unavailable until the snippet contains a working token.

To have a coding agent add the widget for you, go to Build it with a coding agent, select Claude Code, Cursor, or Codex, and click Copy prompt.

In the classic dashboard

To copy the snippet in the classic dashboard, follow these steps:

  1. Open your Product and select the chat Surface.
  2. Select the Ship tab.
  3. Select code it myself in the tool selector.
  4. Select Script tag under Integration format.
  5. In the token menu after with, select a client token, or select Create token… to create one.
  6. Click Copy code.

If you leave a placeholder selected in the token menu, the snippet contains YOUR_CLIENT_TOKEN. Replace it with your client token before you connect the widget.

From the CLI

To create an Agent, a client token, and a script-tag snippet from a terminal, run runtype persona init:

runtype persona init --agent-name "Support" --origins https://example.com --print-snippet

This path creates a new Agent and doesn’t need a Product or a Surface. Set --origins to the origins that host the widget. If you omit --origins in a non-interactive run, the token allows any origin.

Install the widget

To install the widget on an HTML page, paste the copied snippet before the closing </body> tag. Paste it unchanged. The snippet is one script tag that loads the widget installer and carries the client token and your saved settings in its data-config attribute.

To add the widget with default settings, you can write this minimal tag instead:

Script tag
<script
src="https://cdn.runtype.com/persona/latest/install.global.js"
data-runtype-token="YOUR_CLIENT_TOKEN"
></script>

Replace YOUR_CLIENT_TOKEN with your client token.

To keep a production page on a fixed widget version, replace latest in the script URL with a version number, such as 4.24.0. The installer loads the rest of the widget from the same versioned path.

Script tag attributes

The installer reads the following attributes from its script tag:

AttributeValueUse
data-runtype-tokenClient tokenAuthenticates the widget.
data-configJSON objectWidget settings. The copied snippet puts the token and your saved settings here.
data-agent-idAgent IDSelects an Agent that the client token allows.
data-flow-idFlow IDSelects a Flow that the client token allows.
data-api-urlURLSends requests to a different Runtype API URL.
data-preview-paramQuery parameter nameShows the widget only on URLs that carry this parameter.

To test the widget on a live page before visitors can see it, add data-preview-param="chat_preview" to the tag. The widget then appears only on URLs that include ?chat_preview=1.

Configure the widget

In the workbench, use Appearance to configure the widget. In the classic dashboard, click the selected style, such as Clean style, on Ship. Copy the snippet again after you save, because the snippet carries your saved settings. You can configure the following settings:

  • Theme: Set colors, borders, and other styles.
  • Welcome message: Set the first message that visitors see.
  • Launcher: Set the chat bubble’s position and style.

Control the widget from your page

The installer dispatches a persona:chat-ready window event when the chat loads. The event’s detail is the widget handle. With the default floating launcher, the chat loads when a visitor first opens it.

Listen for replies
<script>
window.addEventListener('persona:chat-ready', (event) => {
const handle = event.detail
handle.on('assistant:complete', (message) => {
console.log('Reply', message)
})
})
</script>

The handle has open(), close(), submitMessage(text), and destroy() methods. It emits the user:message, assistant:message, assistant:complete, widget:opened, and widget:closed events.

The data-config attribute holds JSON only. To pass functions, such as event callbacks, set window.siteAgentConfig in a script that runs before the installer script.

Use client tokens

Use a client token to authenticate a browser chat widget. Don’t put an API key in client-side code. Client tokens have the following properties:

  • Public: Designed for browser code. Origin restrictions and scoping limit what a copied token can do.
  • Scoped: Scoped to a Surface, or to specific Agents or Flows.
  • Origin-restricted: Limited to browser origins that match Allowed Origins.

Client tokens use the ct_live_ or ct_test_ prefix. Create and manage them in Access & keys in the workbench or Auth in the classic dashboard. For more information, see Client tokens and domain restrictions.

Restrict widget origins

Set Allowed Origins on the client token in Access & keys or Auth to control which website origins can use the token. Enter each origin with its scheme, such as https://example.com.

Use * to allow any origin. For production, list the exact origins that host the widget. Test tokens also allow localhost origins automatically.

In the workbench, a chat Surface can also have its own Allowed origins list in Access & keys. A request with a token that belongs to that Surface must match both the token list and the Surface list. This also applies to localhost requests from a test token.

Verify the installation

To verify that the widget works, follow these steps:

  1. Save and deploy your HTML changes.
  2. Load the page that contains the script.
  3. Open the chat launcher.
  4. Send a message and confirm that the widget returns a response.
  5. In the workbench, open the Surface’s Embed section and check Origins seen · last 7 days for your page’s origin.

Troubleshoot the widget

Use the following checks when the widget doesn’t work. The browser’s network panel shows the status code and error message for each failed chat request.

Widget doesn’t appear

Check the following items:

  • Place the script before </body>.
  • Check the browser console for errors.
  • If you set data-preview-param, load the page with that query parameter.
  • If your site sends a Content-Security-Policy header, allow https://cdn.runtype.com in script-src and style-src, and https://api.runtype.com in connect-src. A blocked script fails without a visible error on the page.

Widget appears but doesn’t respond

Check the following items:

  • Confirm that the Surface status is Active. An inactive Surface returns 403 with Chat surface is not active.
  • Confirm that the Product has active Capabilities.
  • Confirm that the page origin matches the token’s Allowed Origins and, in the workbench, the Surface’s Allowed origins. An unmatched origin returns 403 with Origin not allowed. If Origins seen · last 7 days shows your origin as Not allowed, click Allow to add it to the selected token.
  • If a request returns 401 with Invalid client token, the token value is wrong or the token was regenerated. Update the snippet with the current token value.
  • If a request returns 403 with Client token is inactive or Client token is no longer active, the token was disabled. Update the snippet with an active token.
  • Review execution logs for errors.

For more origin checks, see Troubleshoot rejected requests.

Conversation stops responding

Check the following items:

  • If a request returns 429 with Session message limit reached, the conversation reached the token’s message limit per session. The default is 100 messages. Start a new conversation, or raise maxMessagesPerSession (up to 1000) on the token through the Client Tokens API.
  • If a request returns 429 with a limit message, your account reached an execution limit. If it returns 402, your account reached its spending limit. Check your usage and billing.

Next steps

Continue with these guides to customize and extend the widget: