---
metadata:
  - name: generator
    content: Diplodoc Platform v5.70.0
alternate:
  - https://divkit.tech/docs/en/quickstart/web.md
  - https://divkit.tech/docs/ru/quickstart/web.md
  - href: https://divkit.tech/docs/ru/quickstart/web.md
    type: text/markdown
    title: Markdown version
  - href: https://divkit.tech/docs/ru/llms.txt?revision=r22102947
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://divkit.tech/docs/ru/llms.txt?revision=r22102947

# Инструкция для Web

DivKit для Web — это npm-пакет `@divkitframework/divkit`. Он отрисовывает JSON-верстку в DOM-элемент в браузере или в HTML-строку на сервере. Чтобы посмотреть, как выглядит верстка, без интеграции в проект, используйте [DivKit Web Playground](https://divkit.tech/docs/ru/concepts/playground.md#web).

## Подключение библиотеки и отрисовка первой карточки {#setup}

### Установка пакета {#install}

Установите пакет из npm:

```bash translate=no
npm i @divkitframework/divkit --save
```

В пакете несколько модулей, и каждый экспортирует функцию `render`. Выберите модуль в зависимости от того, где отрисовывается верстка:

| Модуль | Назначение |
| --- | --- |
| `@divkitframework/divkit/client` | Отрисовка только в браузере. |
| `@divkitframework/divkit/client-hydratable` | Отрисовка в браузере с гидратацией HTML, полученного с сервера. Размер модуля немного больше, чем у `client`. |
| `@divkitframework/divkit/server` | Отрисовка в HTML-строку на сервере. |

Модули поставляются в форматах ES-модулей и CommonJS: Node.js и сборщики сами выбирают подходящий. Описания типов TypeScript входят в пакет.

### Подключение стилей {#css}

При любом способе подключения нужен файл стилей `dist/client.css`. Подключить его можно любым способом. Например, импортируйте файл как модуль, если ваш сборщик обрабатывает CSS:

```js translate=no
import '@divkitframework/divkit/dist/client.css';
```

Или добавьте ссылку на файл в HTML-страницу:

```html translate=no
<link rel="stylesheet" href="node_modules/@divkitframework/divkit/dist/client.css">
```

### Отрисовка на клиенте {#client-render}

Добавьте на страницу элемент, в который будет отрисована карточка:

```html translate=no
<div id="root"></div>
```

Вызовите функцию `render` из модуля `client`. Передайте в нее идентификатор блока, целевой элемент и JSON с версткой. Для примера выведем на экран небольшой текст:

```js translate=no
import { render } from '@divkitframework/divkit/client';
import '@divkitframework/divkit/dist/client.css';

const json = {
    card: {
        log_id: 'text',
        states: [
            {
                state_id: 0,
                div: {
                    type: 'text',
                    text: 'Hello, DivKit!'
                }
            }
        ]
    }
};

const instance = render({
    id: 'hello',
    target: document.querySelector('#root'),
    json,
    onError(details) {
        console.error(details.error);
    }
});
```

Если все сделано без ошибок, на странице появится надпись «Hello, DivKit!». Функция возвращает экземпляр карточки, с помощью которого ее можно [обновить или удалить](#instance).

### Серверная отрисовка и гидратация {#ssr}

На сервере используйте модуль `server`. Его функция `render` не принимает параметр `target` и возвращает HTML-строку:

```js translate=no
import { render } from '@divkitframework/divkit/server';

const html = render({
    id: 'hello',
    json,
    onError(details) {
        console.error(details.error);
    }
});
```

Вставьте полученную строку в элемент-контейнер и подключите к странице файл `dist/client.css`. Чтобы карточка стала интерактивной, в браузере вызовите `render` из модуля `client-hydratable` с параметром `hydrate: true`:

```js translate=no
import { render } from '@divkitframework/divkit/client-hydratable';

render({
    id: 'hello',
    target: document.querySelector('#root'),
    hydrate: true,
    json,
    onError(details) {
        console.error(details.error);
    }
});
```

{% note info %}

Передавайте на сервере и на клиенте одинаковые `id` и `json`. По значению `id` генерируются идентификаторы и классы в разметке.

{% endnote %}

Готовый пример серверной отрисовки с гидратацией доступен на [GitHub](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/ssr).

### Подключение без сборки {#no-build}

Библиотеку можно подключить в браузере и без сборщика, но для рабочих проектов рекомендуется сборка.

{% list tabs %}

- ES-модули

  Импортируйте функцию `render` из файла `dist/esm/client.mjs`:

  ```html translate=no
  <link rel="stylesheet" href="./node_modules/@divkitframework/divkit/dist/client.css">

  <div id="root"></div>

  
  ```

- Глобальная переменная

  Скрипт `dist/browser/client.js` добавляет функцию `render` в глобальный объект `window.Ya.DivKit`:

  ```html translate=no
  <link rel="stylesheet" href="./node_modules/@divkitframework/divkit/dist/client.css">

  <div id="root"></div>

  
  
  ```

  Написание `Ya.Divkit` считается устаревшим — используйте `Ya.DivKit`.

{% endlist %}

### React {#react}

Для React есть отдельный пакет [@divkitframework/react](https://github.com/divkit/divkit/tree/main/client/web/divkit-react). Его компонент `DivKit` принимает параметры функции `render` в виде пропсов.

## Параметры функции render {#render-params}

Параметры `id` и `json` обязательны во всех модулях, параметр `target` — в модулях `client` и `client-hydratable`. Остальные параметры необязательны. В таблице перечислены основные параметры, а полный список с описаниями приведен в [README пакета](https://github.com/divkit/divkit/tree/main/client/web/divkit).

| Параметр | Модули | Описание |
| --- | --- | --- |
| `id` | Все | **string**. Уникальный идентификатор блока. Используется для генерации идентификаторов и классов, поэтому на странице не должно быть двух блоков с одинаковым `id`. |
| `json` | Все | **object**. JSON с версткой: объект `card` и необязательный объект `templates`. |
| `target` | `client`, `client-hydratable` | **HTMLElement**. Элемент, в который отрисовывается карточка. |
| `hydrate` | `client-hydratable` | **boolean**. Укажите `true`, чтобы гидратировать HTML, который уже находится в `target`. |
| `onError` | Все | **function**. Обработчик ошибок и предупреждений. См. раздел [Ошибки](#errors). |
| `onStat` | `client`, `client-hydratable` | **function**. Обработчик для логирования нажатий и показов. См. раздел [Статистика](#stat). |
| `onCustomAction` | `client`, `client-hydratable` | **function**. Обработчик действий, которые DivKit не выполняет сам. См. раздел [Кастомные действия](#custom-actions). |
| `builtinProtocols` | Все | **string[]**. Значение по умолчанию: `['http', 'https', 'tel', 'mailto', 'intent']`. Элементы с действием, протокол которого есть в списке, отрисовываются как ссылки `<a>`, и нажатия на них обрабатывает браузер. |
| `platform` | Все | **string**. Возможные значения: `desktop`, `touch`, `auto`. Значение по умолчанию: `auto`. Настраивает обработку событий мыши или касаний. |
| `direction` | Все | **string**. Возможные значения: `ltr`, `rtl`. Значение по умолчанию: `ltr`. Направление текста и верстки. |
| `theme` | Все | **string**. Возможные значения: `system`, `light`, `dark`. Значение по умолчанию: `system`. См. раздел [Тематизация](#theming). |
| `themeVariableName` | Все | **string**. Имя переменной, в которой хранится текущая тема. См. раздел [Тематизация](#theming). |
| `globalVariablesController` | `client`, `client-hydratable` | **object**. Контроллер внешних переменных. См. раздел [Переменные](#variables). |
| `typefaceProvider` | Все | **function**. Возвращает значение CSS-свойства `font-family` для шрифта из верстки. См. раздел [Шрифты](#fonts). |
| `customComponents` | Все | **Map**. Описания кастомных компонентов. См. раздел [Кастомные компоненты](#custom-components). |
| `extensions` | `client`, `client-hydratable` | **Map**. Расширения, которые подключаются в верстке по идентификатору. См. раздел [Расширения](#extensions). |
| `extensionsForAllComponents` | `client`, `client-hydratable` | **array**. Расширения, которые применяются ко всем элементам. См. раздел [Расширения](#extensions). |
| `fetchInit` | `client`, `client-hydratable` | **object** или **function**. Второй аргумент функции `fetch` для запросов, которые отправляют действия `download` и `submit`. |
| `tooltipRoot` | `client`, `client-hydratable` | **HTMLElement**. Элемент, в который добавляются тултипы и меню вместо `target`. Помогает избежать обрезания. |
| `store` | Все | **object**. Внешнее хранилище для [хранимых значений](../concepts/stored-values.md). Хранилище реализует методы `get` и `set`; метод `get` должен быть синхронным. |
| `videoPlayerProvider` | Все | **object**. Провайдер собственного видеоплеера. На сервере содержит свойство `template` — строку или функцию, которая возвращает разметку плеера; на клиенте — функцию `instance`, которая создает экземпляр плеера. |
| `mix` | Все | **string**. Дополнительный CSS-класс корневого элемента. |
| `customization` | Все | **object**. CSS-классы для кнопок скролла в `gallery` и `pager` на десктопе, а также для всплывающего меню и его пунктов. |

## Обработка действий, статистики и ошибок {#callbacks}

### Кастомные действия {#custom-actions}

Чтобы сделать интерфейс интерактивным, добавьте обработку [действий](https://divkit.tech/docs/ru/concepts/interaction.md). Действия с протоколом `div-action` DivKit выполняет сам, а ссылки с протоколами из списка `builtinProtocols` открывает браузер. Остальные действия передаются в обработчик `onCustomAction`: это ссылки с другими протоколами и действия с `"typed": {"type": "custom"}`.

Для примера превратим текст в кнопку, при нажатии на которую появится уведомление. Добавьте элементу действие:

```json translate=no
"actions": [
    {
        "log_id": "button_pressed",
        "url": "notification://show-toast?text=Hello%2C%20DivKit%21"
    }
]
```

Обработайте это действие в `onCustomAction`:

```js translate=no
render({
    id: 'hello',
    target: document.querySelector('#root'),
    json,
    onCustomAction(action) {
        const [address, query = ''] = (action.url || '').split('?');

        if (address === 'notification://show-toast') {
            alert(new URLSearchParams(query).get('text'));
        }
    }
});
```

Так можно повлиять из JSON-верстки не только на состояние самой карточки, но и на все приложение. Данные действия с `"typed": {"type": "custom"}` передаются в поле `action.payload`. Подробнее — в разделе [Кастомные действия](https://divkit.tech/docs/ru/concepts/interaction.md#custom-actions).

### Статистика {#stat}

Обработчик `onStat` предназначен для логирования нажатий и показов. В поле `details.action` передается действие, а поле `details.type` принимает одно из значений:

- `click` — нажатие на элемент с действием, а также любое действие, у которого нет собственного типа;
- `visible` — показ элемента, для которого заданы `visibility_actions`;
- `disappear` — исчезновение элемента, для которого заданы `disappear_actions`;
- `trigger` — срабатывание [триггера](https://divkit.tech/docs/ru/concepts/triggers.md).

```js translate=no
render({
    id: 'hello',
    target: document.querySelector('#root'),
    json,
    onStat(details) {
        console.log(details.type, details.action.log_id);
    }
});
```

### Ошибки {#errors}

В обработчик `onError` передаются ошибки и предупреждения, которые возникают при разборе и отрисовке верстки. У объекта `details.error` есть поле `level` со значением `error` или `warn` и необязательное поле `additional` с дополнительными данными. Если обработчик не задан, DivKit выводит сообщения в консоль.

```js translate=no
render({
    id: 'hello',
    target: document.querySelector('#root'),
    json,
    onError(details) {
        const { level, message, additional } = details.error;

        console.log(level, message, additional);
    }
});
```

## Тематизация {#theming}

Параметр `theme` задает тему карточки: `light`, `dark` или `system`. Со значением `system`, которое используется по умолчанию, тема определяется по настройкам системы пользователя (медиавыражение `prefers-color-scheme`) и меняется вместе с ними. На сервере настройки системы недоступны, поэтому со значением `system` верстка отрисовывается в светлой теме.

Чтобы использовать текущую тему в верстке, укажите в параметре `themeVariableName` имя переменной. DivKit создаст строковую переменную с этим именем и будет записывать в нее значение `light` или `dark`. Используйте переменную в [выражениях](https://divkit.tech/docs/ru/concepts/expressions.md): при смене темы зависящие от нее свойства обновятся без перезагрузки страницы.

{% note info %}

Если параметр `themeVariableName` не передан, переменная не создается. Имя переменной не должно совпадать с именами переменных карточки и внешних переменных, иначе DivKit сообщит об ошибке `Duplicate variable`.

{% endnote %}

```js translate=no
render({
    id: 'themed',
    target: document.querySelector('#root'),
    json,
    theme: 'system',
    themeVariableName: 'theme'
});
```

{% cut "Посмотреть пример верстки" %}

```json translate=no
{
    "card": {
        "log_id": "themed_card",
        "states": [
            {
                "state_id": 0,
                "div": {
                    "type": "text",
                    "text": "Hello, DivKit!",
                    "text_color": "@{theme == 'dark' ? '#ffffff' : '#000000'}",
                    "background": [
                        {
                            "type": "solid",
                            "color": "@{theme == 'dark' ? '#000000' : '#ffffff'}"
                        }
                    ]
                }
            }
        ]
    }
}
```

{% endcut %}

Тему уже отрисованной карточки меняет метод экземпляра `setTheme`, например `instance.setTheme('dark')`. В описаниях типов пакета этот метод помечен как устаревший.

## Переменные {#variables}

Модули `client` и `client-hydratable` экспортируют функции для работы с [внешними переменными](https://divkit.tech/docs/ru/concepts/variables.md#global). Функция `createVariable` создает переменную, а `createGlobalVariablesController` — контроллер, через который переменные становятся доступны в карточке. Чтобы несколько карточек использовали общие переменные, передайте один и тот же контроллер в каждый вызов `render`.

```js translate=no
import {
    render,
    createVariable,
    createGlobalVariablesController
} from '@divkitframework/divkit/client';

const userName = createVariable('user_name', 'string', 'Guest');

const controller = createGlobalVariablesController();
controller.setVariable(userName);

render({
    id: 'hello',
    target: document.querySelector('#root'),
    json,
    globalVariablesController: controller
});

const unsubscribe = userName.subscribe(value => {
    console.log(value);
});

userName.setValue('Alice');
```

В верстке переменная доступна по имени, например `@{user_name}`. Методы переменной:

- `subscribe` — вызывает обработчик с текущим значением и затем при каждом его изменении. Возвращает функцию для отписки.
- `setValue` — записывает новое значение.
- `getValue` — возвращает текущее значение.

Имена переменных в одном контроллере должны быть уникальными: при добавлении второй переменной с тем же именем метод `setVariable` выбрасывает исключение.

## Расширение возможностей {#extending}

### Кастомные компоненты {#custom-components}

Элемент [custom](https://divkit.tech/docs/ru/concepts/divs/2/div-custom.md) отрисовывается с помощью пользовательских элементов HTML (Custom Elements). Передайте в параметре `customComponents` объект `Map`, в котором ключ — значение `custom_type` из верстки, а значение — описание компонента с именем тега в поле `element`:

```js translate=no
import { render } from '@divkitframework/divkit/client';

class CustomCard extends HTMLElement {
    connectedCallback() {
        this.textContent = `Start: ${this.getAttribute('start')}`;
    }
}

customElements.define('custom-card', CustomCard);

render({
    id: 'custom',
    target: document.querySelector('#root'),
    json: {
        card: {
            log_id: 'custom_card',
            states: [
                {
                    state_id: 0,
                    div: {
                        type: 'custom',
                        custom_type: 'custom_card',
                        custom_props: {
                            start: 15
                        }
                    }
                }
            ]
        }
    },
    customComponents: new Map([
        ['custom_card', { element: 'custom-card' }]
    ])
});
```

Свойства из `custom_props` передаются компоненту в виде HTML-атрибутов. Кастомные компоненты поддерживаются и при серверной отрисовке: разметку компонента для сервера можно передать в поле `template` описания.

Примеры на GitHub:

- [простой компонент](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/custom-simple);
- [компонент с дочерними элементами DivKit](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/custom-container);
- [компонент и серверная отрисовка](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/custom-ssr).

### Расширения {#extensions}

По умолчанию ни одно расширение не подключено. Чтобы включить расширение, передайте в параметре `extensions` объект `Map`: ключ — идентификатор расширения из поля `extensions` элемента, значение — класс расширения. Модули `client` и `client-hydratable` экспортируют готовые расширения `SizeProvider` и `Gesture`, а также функции `lottieExtensionBuilder` и `markdownExtensionBuilder`, которые создают расширения для Lottie и Markdown.

```js translate=no
import { render, SizeProvider } from '@divkitframework/divkit/client';

render({
    id: 'hello',
    target: document.querySelector('#root'),
    json,
    extensions: new Map([
        ['size_provider', SizeProvider]
    ])
});
```

Расширения работают только на клиенте. Если страница отрисована на сервере, а расширение меняет внешний вид элемента, пользователь может заметить это изменение при загрузке страницы.

Подробнее о расширениях и параметре `extensionsForAllComponents` — в разделе [Подключение](https://divkit.tech/docs/ru/concepts/extensions.md#connect).

### Шрифты {#fonts}

Шрифты подключаются на странице средствами CSS. Чтобы сопоставить имя шрифта из параметра `font_family` с CSS-шрифтом, передайте функцию `typefaceProvider`. Она получает имя шрифта и необязательный объект с насыщенностью `fontWeight` и возвращает значение CSS-свойства `font-family`:

```js translate=no
render({
    id: 'hello',
    target: document.querySelector('#root'),
    json,
    typefaceProvider(fontFamily, opts) {
        if (fontFamily === 'display') {
            return '"My Display Font", sans-serif';
        }

        return '';
    }
});
```

Подробнее — в разделе [Шрифты](https://divkit.tech/docs/ru/quickstart/resources.md#fonts-web).

## Обновление и удаление карточки {#instance}

Функция `render` из модулей `client` и `client-hydratable` возвращает экземпляр карточки. Его методы:

| Метод | Описание |
| --- | --- |
| `execAction(action)` | Выполняет [действие](../concepts/interaction.md) в карточке. |
| `applyPatch(patch)` | Применяет [патч](../concepts/patches.md#patch-format). Возвращает `true`, если патч применен. |
| `setData(json)` | Перерисовывает карточку по новому JSON. Метод экспериментальный: его логика и API могут измениться. |
| `$destroy()` | Уничтожает экземпляр и удаляет карточку со страницы. |

```js translate=no
instance.execAction({
    log_id: 'reset_counter',
    url: 'div-action://set_variable?name=counter&value=0'
});

instance.$destroy();
```

Метод `setData` старается сохранить состояние карточки, например значения в полях ввода. Он не меняет существующие переменные и триггеры, а только создает новые переменные.

## Требования к окружению {#requirements}

Поддерживаемые браузеры:

```translate=no
chrome >= 67
safari >= 14
firefox >= 68
```

Для отдельных возможностей нужны более новые браузеры. Например, параметр `aspect` элемента `container` требует поддержки CSS-свойства `aspect-ratio`.

Для серверной отрисовки:

```translate=no
Node.js >= 14
```

Целые числа DivKit хранит в типе `BigInt`, если платформа его поддерживает. Учитывайте, что `JSON.parse` и метод `json()` ответа `fetch` возвращают большие целые числа как `number`, поэтому значения больше `2^53` могут потерять точность еще до передачи в DivKit.

## Примеры проектов {#samples}

Готовые к запуску примеры доступны на [GitHub](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples):

- [js](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/js) и [ts](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/ts) — подключение со сборкой;
- [globals](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/globals) и [globals-esm](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/globals-esm) — подключение без сборки;
- [ssr](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/ssr) и [node-esm](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/node-esm) — серверная отрисовка;
- [divkit-react](https://github.com/divkit/divkit/tree/main/client/web/divkit-examples/divkit-react) — React с серверной отрисовкой.

<!-- source: ru/_includes/index/troubleshooting.md -->
## Узнать больше {#troubleshooting}

Вы можете обсуждать интересующие вас темы в сообществе пользователей DivKit в Telegram: [https://t.me/divkit_community_ru](https://t.me/divkit_community_ru).



[Репозиторий DivKit](https://github.com/divkit/divkit)




<!-- endsource: ru/_includes/index/troubleshooting.md -->
