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:
- Open the chat Surface and select Embed.
- Select Script tag.
- In the token menu, select a client token, or select Create token… to create one.
- 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.
- 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:
- Open your Product and select the chat Surface.
- Select the Ship tab.
- Select code it myself in the tool selector.
- Select Script tag under Integration format.
- In the token menu after with, select a client token, or select Create token… to create one.
- 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:
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:
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:
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.
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:
- Save and deploy your HTML changes.
- Load the page that contains the script.
- Open the chat launcher.
- Send a message and confirm that the widget returns a response.
- 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.cominscript-srcandstyle-src, andhttps://api.runtype.cominconnect-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
403withChat 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
403withOrigin 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
401withInvalid client token, the token value is wrong or the token was regenerated. Update the snippet with the current token value. - If a request returns
403withClient token is inactiveorClient 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
429withSession message limit reached, the conversation reached the token’s message limit per session. The default is 100 messages. Start a new conversation, or raisemaxMessagesPerSession(up to 1000) on the token through the Client Tokens API. - If a request returns
429with a limit message, your account reached an execution limit. If it returns402, your account reached its spending limit. Check your usage and billing.
Next steps
Continue with these guides to customize and extend the widget:
- Widget theming and customization: change the widget’s appearance and behavior.
- Client tokens and domain restrictions: manage the origins that can use the client token.
- End-user identity and credentials: pass a proof from your backend so a visitor’s history follows them across devices.
- Conversation history in an embedded widget: let visitors return to earlier conversations.
- Build the widget from code: create the Agent and its client token with the SDK.