Три составляющих Web Components

Web Components — не один API, а набор из трёх браузерных стандартов, которые работают совместно.

Custom Elements

Custom Elements позволяют зарегистрировать новый HTML-тег с собственным поведением:

class RecommendationWidget extends HTMLElement {
  connectedCallback() {
    this.render();
  }
  render() {
    this.innerHTML = `<div class="reco-list">...</div>`;
  }
}
customElements.define('recommendation-widget', RecommendationWidget);

После регистрации тег <recommendation-widget> работает в любом HTML-документе как стандартный элемент.

Shadow DOM

Shadow DOM создаёт изолированное поддерево DOM. CSS внутри shadow root не конфликтует с глобальными стилями хост-страницы:

class RecommendationWidget extends HTMLElement {
  connectedCallback() {
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `
      <style>
        /* Эти стили не вытекут на основную страницу */
        .title { font-size: 18px; color: #333; }
      </style>
      <div class="title">Похожие товары</div>
    `;
  }
}

Это ключевое преимущество при распространении виджетов персонализации: виджет выглядит одинаково на сайтах с разными CSS-архитектурами.

HTML Templates

Элемент <template> объявляет разметку, которая не рендерится до явного клонирования. <slot> позволяет вставлять контент снаружи в определённые места компонента — аналог props в React.

Когда Web Components уместны

Сценарий Web Components React/Vue
Виджет для клиентов с разными стеками ✓ Предпочтительно ✗ Требует согласования
SaaS-виджет с изоляцией стилей ✓ Shadow DOM ✗ Глобальные стили конфликтуют
Сложное внутреннее приложение Менее удобно ✓ Экосистема, инструменты
Максимальная производительность ✓ Нет оверхеда фреймворка Зависит от реализации

Web Components в платформах персонализации

Для SaaS-платформ, которые распространяют виджеты рекомендаций или онсайт-персонализации, Web Components решают принципиальную проблему: клиенты используют разные фреймворки, версии и сборщики. Виджет на чистых Custom Elements + Shadow DOM встраивается в одну строку:

<script src="https://platform.example/widget.js"></script>
<recommendation-widget placement="pdp" strategy="similar-items"></recommendation-widget>

Это снижает барьер интеграции для клиентов с нестандартными стеками и уменьшает нагрузку на команду разработки платформы — не нужно поддерживать SDK отдельно под React, Vue и Angular.

Совет: Shadow DOM по умолчанию не наследует CSS-переменные хост-страницы. Если нужна тематизация под стиль клиентского сайта — передавайте CSS-переменные через атрибуты или используйте mode: 'open' с осторожностью.