enВойти в Senler

Встраивание в контейнер

Сначала подключите скрипт-загрузчик. Режим 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. Справочник методов.