ruLog in to Senler

Widget Initialization Parameters

First create a channel and obtain the code in Embed Code. If the cabinet settings are sufficient, paste the generated code unchanged. This page is for developers who embed the chat in their own container, pass authenticated visitor data, or control configuration from code.

Where to Start

Decide two things:

  1. Where the chat belongs: over the page (popup) or inside your own block (embedded).
  2. Where appearance and features come from: saved channel settings (remote) or site code (local).

For most sites, popup with config_source: "remote" is the simplest choice: saved cabinet changes appear without replacing the code. Use local when the site itself versions and controls the settings.

Placement Mode

  • popup opens over the page from a floating button;
  • embedded occupies the supplied container and has no floating button.

For embedded, pass an existing CSS selector or DOM Element. Initialization fails if the container cannot be found. open(), close(), and toggle() work in both modes.

button_only: true renders only the floating-button appearance without a chat iframe. The button is not interactive, open(), close(), and toggle() open nothing, and isOpen() returns false. This mode is intended for a standalone button preview and cannot be combined with embedded. Because no iframe is created and remote channel settings are not loaded, define its appearance through theme.button in the site code.

Configuration Source

  • Dynamic in the cabinet corresponds to config_source: "remote": theme and features load from saved channel settings. Language and placement remain in the site's code. Change persistent theme and features settings in the cabinet; on initial load, only theme_mode from a supplied theme object is used as a light, dark, or system-theme override.
  • Static corresponds to config_source: "local": theme and features are included in the code. After changing persistent settings, copy the new code and update it on the site.

Choose the mode in Embed code. In the screenshot, 1 marks Static, 2 marks Dynamic, and 3 marks visitor identity linking. The generated code appears below this selector.

Choosing the settings source and identity linking

The cabinet preview may show unsaved changes, but it does not change the configuration of the live site.

Embed the Widget in a Container

This step applies only to embedded mode. The container must have actual dimensions: the widget occupies 100% of its width and height. theme.width and theme.height size the popup window and do not replace the container dimensions.

<div id="senler-widget" style="width: 100%; height: 600px"></div>

<!-- Load the loader script from the generated channel code before this block. -->
<script>
  SenlerWidget.init({
    channel_id: "xxx",
    config_source: "local",
    display_mode: "embedded",
    container: "#senler-widget",
    theme: {
      border_radius: 18,
    },
    features: {
      element_selection: true,
    },
  });
</script>

This example places the chat in #senler-widget and enables page-element selection. Take the loader-script URL and the real channel_id from the generated cabinet code. Add authenticated visitor data only with the server-side signature described below.

Visitor Data

user contains the data Senler uses to create or update the widget lead. Pass only information about the current visitor that your data-processing policy allows.

FieldWhat to pass and how it is used
external_idA stable authenticated-user ID from your system. When it is present, user_hash is required.
user_hashAn HMAC-SHA256 signature of external_id, calculated by the site backend with the channel secret and encoded as 64 hexadecimal characters.
emailThe lead email. A non-empty value is saved on creation and updates an existing lead.
phoneThe loader and API accept a string, but the current version does not save it to the lead profile. Do not rely on this field until the server contract changes.
first_name, last_nameThe lead's first and last name. Non-empty values are saved on creation and update.
avatar_urlA public HTTPS URL without embedded credentials. An explicitly passed empty, invalid, or local value means no avatar and removes the existing lead's previously saved avatar.
dataA plain JSON-compatible object with additional data. On repeat initialization, a non-empty object is shallow-merged into saved data; omitted keys are not deleted.

Always pass external_id together with user_hash: initialization is rejected without the signature. The cabinet identity-linking switch adds these fields to generated code and exposes the secret and backend examples; it does not enable or disable the verification itself. Never put the secret in HTML, loader configuration, or any other browser code. Linking to an Authorized User shows the complete setup.

For example, a Node.js backend signs the exact external_id value as follows:

import { createHmac } from "node:crypto";

const userHash = createHmac("sha256", channelSecret)
  .update(externalId)
  .digest("hex");

Send only the externalId and resulting userHash values to the browser as external_id and user_hash. Keep channelSecret on the server.

With a signed identity link, history belongs to the same account across devices. Without external_id, Senler creates an anonymous browser session, so previous history is unavailable after switching browser or device.

To avoid assembling user manually, click the gear button next to the generated code. It is marked 1 in the screenshot and opens Code building example.

Button that opens the code building example

In the dialog, select the required fields and copy the result. For user.data, enter a key in 9 and a value in 10; add a row with 11, remove a row with 12, and copy the generated example with 13. The builder demonstrates the accepted data shape but does not change the channel's primary code. phone is present even though the current backend does not persist it.

Additional data and copying the generated code example

Appearance

theme supports:

KeyWhat the visitor sees
chat_titleChat heading.
default_dialog_titleName of a new dialog.
theme_modeLight, dark, or system theme: light, dark, auto.
positionPopup position: bottom-right, bottom-left, top-right, top-left.
width, heightWindow size: width 200–800, height 300–1000 pixels.
border_radiusCorner radius from 0 to 50 pixels.
shadow_enabledWindow shadow.
welcome_messagePlaceholder in the message input. The technical key name is retained for compatibility.
empty_state_messageGreeting in an empty new dialog.
welcome_buttonsQuick questions before the conversation starts.
buttonFloating-button position and colors.

Localized text accepts { ru?: string, en?: string }. Each welcome_buttons array may contain up to 8 non-empty unique strings of no more than 120 characters. Clicking a button immediately sends its text.

SenlerWidget.init({
  channel_id: "xxx",
  config_source: "local",
  theme: {
    empty_state_message: {
      ru: "Здравствуйте! Чем помочь?",
      en: "Hello! How can I help?",
    },
    welcome_buttons: {
      ru: ["Узнать цену", "Связаться с оператором"],
      en: ["Check the price", "Contact an operator"],
    },
  },
});

theme.button.position accepts the same four positions plus hidden. Use theme.button.position: "hidden" to hide the floating button; theme.position: "hidden" is invalid. Set theme.button.light.background, theme.button.light.icon, theme.button.dark.background, and theme.button.dark.icon in #RRGGBB format.

welcome_buttons cannot be changed through updateRuntime. In remote mode, save them in the cabinet. In local mode, update the code and initialize the widget again.

Chat Features

features keyWhat it enablesDefault
file_uploadFile attachments.true
voice_messagesVoice-message recording.false
emojiEmoji picker.true
split_viewAt widths of 640 pixels and above, shows the dialog list beside the current chat.true
element_selectionSelecting an element on the host page for a question.false

The element_selection flag alone is not enough for stable references. Add data-ai-* markup so labels remain clear and elements can be found again.

init Parameter Reference

The loader accepts only supported top-level keys:

KeyTypeRequired / defaultPurpose
channel_idstringRequiredWidget channel ID from the generated code.
userobjectOptionalVisitor data. Whenever external_id is supplied, it must have a server-generated user_hash.
themeobjectOptionalAppearance, popup dimensions, text, and floating button for config_source: "local". With remote, only the initial theme_mode is read from this object.
featuresobjectOptionalChat features for config_source: "local".
lang"ru" | "en" | "auto""auto"Interface language.
config_source"local" | "remote""remote"Settings in code or saved channel settings.
display_mode"popup" | "embedded""popup"Chat placement mode.
button_onlybooleanfalseA non-interactive floating button without a chat iframe. Incompatible with embedded.
containerCSS selector or DOM ElementRequired for embeddedEmbedded-widget container. Pass it at popup startup as well if you will switch modes through the Public API later.
shellobjectEmpty objectcollapse_button and mobile_edge_swipe; both are off until set to true.
onCollapsefunctionOptionalCallback for an embedded-widget collapse request.
contextProviderfunctionOptionalSynchronous provider of persistent page context.
customActionsobjectEmpty setSite buttons and actions available in chat.
customActionsLanguage"ru" | "en"Not setDescription language for customActions.
debugbooleanfalseAdditional loader console messages.

Other top-level keys are errors. Calling SenlerWidget.init(...) again destroys the current instance and creates a new one, so use Public API methods for temporary changes.

If Loading Is Delayed

The progress indicator appears when loading exceeds 4 seconds. After 10 seconds, the loader displays “Loading is taking longer. We are still retrying.” and a Copy for Support button. This is informational: automatic retries continue.

The report contains loader and protocol versions, attempt number, duration and failure stage, network state, and resource checks. Query parameters, request contents, channel and user IDs, and tokens are excluded.

The external report covers iframe startup. If an error occurs inside an already loaded chat, use the action shown in that particular interface message. Do not promise a retry button when a specific state does not provide one.

What to Configure Next

After initialization works, follow Page and Message Context to pass the current screen and relevant business object to the agent. Start marking buttons and fields only after an ordinary message and context work independently.