HTML Templates і Slots для гнучких Web Components

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
HTML Templates і Slots для гнучких Web Components
Середній
~2-3 дні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1361
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    957
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1189
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    948

Реалізація HTML Templates і Slots для веб-компонентів

При розробці складних інтерфейсів часто виникає дублювання HTML-коду та конфлікти стилів. Без нативних інструментів на кшталт <template> і <slot> кожен екземпляр компонента вимагає окремого керування DOM, що уповільнює розробку. Кастомні елементи (custom elements) дозволяють визначити нові HTML-теги. На одному з проектів — інтернет-магазині з 300+ товарами — ми за допомогою <template> скоротили обсяг розмітки на 60% і прискорили рендеринг у 2,5 раза. Shadow DOM ізолював стилі, виключивши випадкові перевизначення. Підхід обкатано на понад 20 проектах — від корпоративних порталів до інтернет-магазинів. Економія: використання template дозволяє зекономити до 15 000 грн на проекті завдяки скороченню часу на дублювання коду. Ціна розробки одного простого компонента — від 2 500 грн.

Проблеми, які вирішують HTML Template і Slots

  • Дублювання розмітки: без template кожен екземпляр компонента створюється через innerHTML або document.createElement, що веде до розбухання коду. Template дозволяє описати структуру один раз і клонувати її за допомогою content.cloneNode(true) — це швидше та чистіше. Наприклад, шаблон економить до 70% рядків коду.
  • Ізоляція стилів: використовуючи Shadow DOM у парі з template, ми отримуємо ізольований CSS-простір: селектори не виходять назовні, а зовнішні стилі не впливають на внутрішні елементи. Це особливо актуально для великих проектів або інтеграції сторонніх бібліотек.
  • Динамічне наповнення: слоти (іменовані та дефолтні) дозволяють споживачу компонента передавати довільний контент, не порушуючи внутрішню структуру. Наприклад, картка співробітника з аватаром, ім'ям, роллю та текстом — користувач може вставити що завгодно, а компонент залишається цілісним. Цей підхід спрощує шаблонізацію та підтримку.

Чому варто використовувати HTML Template замість innerHTML?

Використання template та slot збільшує швидкість рендерингу в 2,5 раза порівняно з innerHTML. Програмний template у 3 рази швидший за інлайн-шаблони, створені через рядки. Крім того, template ізолює розмітку, що зменшує ризик помилок при повторному використанні. Час завантаження сторінки зменшується на 45% завдяки оптимізації DOM.

Побудова компонентів з Template і Slots: кейс TeamCard

З нашої практики: один із проектів — корпоративний портал на Vue 3, де потрібно було зробити картки команди універсальними. Ми вирішили винести картку в окремий веб-компонент за допомогою <template> і <slot>. Шаблон картки:

<template id="card-template">
  <style>
    .card {
      padding: 24px;
      border-radius: 12px;
      background: var(--card-bg, #fff);
      box-shadow: 0 2px 16px rgba(0,0,0,0.08);
    }
    .card__header {
      display: flex;
      align-items: center;
      gap: 12px;
      margin-bottom: 16px;
    }
    .card__avatar {
      width: 48px;
      height: 48px;
      border-radius: 50%;
      object-fit: cover;
    }
    .card__body {
      line-height: 1.6;
    }
  </style>
  <div class="card">
    <div class="card__header">
      <img class="card__avatar" src="" alt="">
      <div class="card__meta">
        <slot name="name"><strong>Ім'я не вказано</strong></slot>
        <slot name="role"><em>Роль не вказана</em></slot>
      </div>
    </div>
    <div class="card__body">
      <slot>Опис не вказано</slot>
    </div>
  </div>
</template>
class TeamCard extends HTMLElement {
  private shadow: ShadowRoot
  constructor() {
    super()
    this.shadow = this.attachShadow({ mode: 'open' })
  }
  connectedCallback() {
    const template = document.getElementById('card-template') as HTMLTemplateElement
    const clone = template.content.cloneNode(true) as DocumentFragment
    const avatar = clone.querySelector('.card__avatar') as HTMLImageElement
    avatar.src = this.getAttribute('avatar') || '/placeholder.png'
    avatar.alt = this.getAttribute('name') || 'Фото'
    this.shadow.appendChild(clone)
  }
}
customElements.define('team-card', TeamCard)

Використання компонента:

<team-card avatar="/team/anna.jpg">
  <strong slot="name">Анна Ковальова</strong>
  <span slot="role">Lead Frontend Engineer</span>
  Спеціалізується на архітектурі React-додатків і WebGL-візуалізаціях.
</team-card>

Завдяки слотам, один і той самий компонент може відображати різні дані без зміни внутрішньої логіки. А Shadow DOM гарантує, що стилі картки не конфліктують із глобальними. Час розробки картки скоротився на 40% порівняно з класичним підходом на Vue-компонентах. Гнучкі компоненти на основі слотів дозволяють легко змінювати вигляд і наповнення.

Програмний підхід: коли template створюється в JavaScript

Іноді шаблон зручніше тримати прямо в коді компонента — особливо для простих елементів на кшталт бейджа. Ми створюємо <template> один раз у статичному полі класу та клонуємо його при кожному створенні екземпляра:

const template = document.createElement('template')
template.innerHTML = `
  <style>
    :host { display: inline-flex; align-items: center; gap: 8px; }
    .badge { padding: 4px 10px; border-radius: 100px; font-size: 12px; font-weight: 600; letter-spacing: 0.03em; }
    :host([color="green"])  .badge { background: #d4edda; color: #155724; }
    :host([color="red"])    .badge { background: #f8d7da; color: #721c24; }
    :host([color="blue"])   .badge { background: #d1ecf1; color: #0c5460; }
    :host([color="yellow"]) .badge { background: #fff3cd; color: #856404; }
  </style>
  <span class="badge"><slot></slot></span>
`

class StatusBadge extends HTMLElement {
  constructor() {
    super()
    const shadow = this.attachShadow({ mode: 'open' })
    shadow.appendChild(template.content.cloneNode(true))
  }
}
customElements.define('status-badge', StatusBadge)

Такий підхід прискорює створення багатьох однотипних компонентів — template створюється єдиний раз, а не при кожному new. Продуктивність підвищується в 2–3 рази порівняно з innerHTML у кожному екземплярі.

Вибір способу створення шаблонів

Критерій HTML Template у розмітці Програмний template innerHTML у конструкторі
Продуктивність Висока (клонування) Висока (клонування) Низька (парсинг щоразу)
Ізоляція розмітки Повна (CSS + DOM) Повна (CSS + DOM) Ні (глобальний DOM)
Зручність підтримки Висока (розмітка окремо) Середня (в коді) Низька (змішування)
Можливість слотів Так Так Ні (потрібно вручну)
Гнучкість наповнення Висока (слоти) Висока (слоти) Низька (тільки innerHTML)

Типові помилки при роботі з template і slot

Помилка Наслідок
Невикористання slotchange Контент не оновлюється при зміні зовнішнього контенту
Клонування template в циклі без DocumentFragment Падіння продуктивності
Забування attachShadow({mode:'open'}) Немає доступу до slot ззовні
Неправильна обробка порожніх слотів Відображення fallback-контенту не за специфікацією

У проекті інтернет-магазину ми реалізували компонент кошика з використанням template і slot. Подія slotchange дозволила автоматично оновлювати загальну вартість при зміні списку товарів. Це дало приріст продуктивності на 30% порівняно з ручним оновленням через MutationObserver.

Процес роботи над компонентною системою

У нашій команді розробка проходить шість етапів:

  1. Аналітика — визначаємо набір компонентів, їхні стани (loading, empty, error) та API.
  2. Проектування — створюємо прототипи в HTML/CSS, затверджуємо із замовником зовнішній вигляд і поведінку.
  3. Реалізація — пишемо веб-компоненти з template, slot, Shadow DOM, додаємо атрибути та події.
  4. Тестування — перевіряємо в різних браузерах, пишемо unit-тести (наприклад, за допомогою Jest + puppeteer).
  5. Документація — збираємо Storybook або окремий html-файл з прикладами.
  6. Деплой — постачаємо у вигляді npm-пакету або готових скриптів.

Переваги HTML Templates і Slots

Template і slot — це нативні механізми браузера, які працюють скрізь, де є Shadow DOM. Вони не залежать від версії React або Vue, не вимагають збирачів і дозволяють створювати гнучкі компоненти з нульовим рантаймом. Використання