Skip to content

Widget mode

Reactive Route можно отвязать от window.history и использовать в режиме виджетов, полноценно и без iframe встраивая в сайты. Здесь был взят вариант c Solid.js из Примеров с заменой await router.init(location.href) на этот код:

ts
import { createRenderEffect } from 'solid-js';

router.historySyncStop();

await router.init(localStorage.getItem('WIDGET_URL') || '/');

// save to external storage
createRenderEffect(() => {
  const currentUrl = router.activeName
    ? router.stateToUrl(router.state[router.activeName])
    : '/';

  localStorage.setItem('WIDGET_URL', currentUrl);
});

// restore from external storage
window.addEventListener('storage', (event) => {
  if (event.key === 'WIDGET_URL') {
    router.redirect(router.urlToState(event.newValue || '/'));
  }
});

Слушать за событием 'storage' нужно только если планируется управлять виджетом из-вне: достаточно записать новый URL в localStorage и в ряде случаев вызвать это событие вручную по спецификации бразуера. Так, две кнопки ниже — нативные для Vitepress (Vue) и при клике выполняют следующий код:

ts
function setWidgetUrl(url: string) {
  localStorage.setItem('WIDGET_URL', url);

  window.dispatchEvent(
    new StorageEvent('storage', {
      key: 'WIDGET_URL',
      newValue: url,
      storageArea: localStorage,
    })
  );
}

Размер js-бандла для этого виджета в сжатом виде 13.3 KB, при этом в нем полноценная система реактивности и рендеринга + Reactive Route. Разумеется, можно встраивать несколько виджетов на разных стеках, и даже крупные сайты и админ-панели, а также проектировать микрофронтенды. Главное — обеспечить изоляцию стилей и переменных, правильно настроив бандлер.

No AI participated in the development. MIT License