Встраивание в контейнер
Сначала подключите скрипт-загрузчик. Режим embedded размещает чат в контейнере сайта; режим popup показывает отдельное окно. button_only несовместим с embedded.
Встройте виджет в контейнер
Этот шаг нужен только для режима embedded. У контейнера должны быть реальные размеры: виджет занимает 100% его ширины и высоты. Параметры theme.width и theme.height задают размер popup-окна и не заменяют размеры контейнера.
<div id="senler-widget" style="width: 100%; height: 600px"></div>
<!-- Перед этим кодом подключите скрипт-загрузчик из готового кода канала. -->
<script>
SenlerWidget.init({
channel_id: "xxx",
display_mode: "embedded",
container: "#senler-widget",
theme: {
border_radius: 18,
},
features: {
element_selection: true,
},
});
</script>
Этот пример размещает чат в #senler-widget и включает выбор элементов страницы. URL скрипта-загрузчика и настоящий channel_id возьмите из готового кода в кабинете. Данные авторизованного посетителя добавляйте только вместе с серверной подписью.
Виджет внутри скрываемой панели
Если сайт прячет embedded-виджет в собственной панели или вкладке, сообщайте ему, виден ли чат посетителю. Для изначально скрытой панели передайте surfaceVisible: false при init, затем обновляйте значение вместе с показом и скрытием панели:
<button onclick="setChatPanelVisible(true)">Открыть чат</button>
<div id="chat-panel" hidden>
<button onclick="setChatPanelVisible(false)">Закрыть чат</button>
<div id="senler-widget" style="height: 600px"></div>
</div>
<script>
// Подключите скрипт-загрузчик из готового кода канала перед этим примером.
SenlerWidget.init({
channel_id: "xxx",
display_mode: "embedded",
container: "#senler-widget",
surfaceVisible: false,
});
function setChatPanelVisible(visible) {
document.getElementById("chat-panel").hidden = !visible;
SenlerWidget.updateRuntime({ surfaceVisible: visible });
}
</script>
surfaceVisible управляет учётом прочтения, а не оформлением: сам по себе параметр не скрывает и не открывает контейнер. В скрытой панели или фоновой вкладке браузера сообщения не отмечаются прочитанными. Авторизация, явно отправленные запросы и WebMCP при этом продолжают работать. Открытие и закрытие штатного popup-окна, а также вызовы open() и close() учитываются автоматически.
В React передавайте актуальную видимость через runtime={{ surfaceVisible: panelIsVisible }}; менять config и пересоздавать виджет не нужно. Пример подключения React.
Сворачивание embedded-виджета
В popup крестик уже есть в шапке и скрывает окно. Плавающая кнопка открывает тот же экземпляр снова.
В embedded-режиме включите shell.collapse_button: true, если пользователю нужна кнопка сворачивания в шапке. Кнопка только сообщает сайту о намерении свернуть виджет: сайт сам вызывает SenlerWidget.close() или закрывает внешнюю панель.
SenlerWidget.init({
channel_id: "xxx",
display_mode: "embedded",
container: "#senler-widget",
shell: {
collapse_button: true,
},
onCollapse(detail) {
console.log("Пользователь запросил сворачивание", detail);
SenlerWidget.close();
},
});
Вместо onCollapse можно один раз подписаться на событие:
window.addEventListener("senler-widget:collapse-request", (event) => {
if (event.detail.display_mode === "embedded") {
SenlerWidget.close();
}
});
В detail приходят channel_id и display_mode. Если настроить и callback, и событие, сработают оба обработчика. Обычно выбирайте один способ, чтобы не выполнить сворачивание дважды.
CLOSE_WIDGET и COLLAPSE_WIDGET — внутренние сообщения протокола iframe. Сайт не должен отправлять их через postMessage.
Мобильный жест
shell.mobile_edge_swipe: true включает свайп от левого края внутри виджета. Скрипт-загрузчик не закрывает интерфейс, а отправляет senler-widget:mobile-edge-swipe.
window.addEventListener("senler-widget:mobile-edge-swipe", (event) => {
if (event.detail.side === "left") {
closeMobilePanel();
}
});
В detail приходят channel_id, display_mode и side: "left". Это навигационный сигнал для сайта, а не замена кнопки сворачивания.
Для обычного скрытия используйте SenlerWidget.close(): он скрывает и embedded-обёртку, сохраняя состояние. SenlerWidget.open() показывает тот же экземпляр. SenlerWidget.destroy() удаляет виджет; после него нужен новый init. Справочник методов.