---
title: "Класс Blok — new Blok(), isReady, destroy"
description: "Создание, ожидание готовности и уничтожение экземпляра редактора, а также что безопасно вызывать до isReady."
source: https://blokeditor.com/ru/docs/core/
lastmod: 2026-10-07
---

Фреймворк JavaScript

Основное Класс Blok

На этой странице save()

# Класс Blok: создание и уничтожение редактора

Главный класс редактора. Он создаёт экземпляр редактора Blok и управляет им. Любое пространство имён, доступное инструменту через `api.*`, есть и на самом экземпляре как `editor.*`. Свойства ниже описывают ту же поверхность плюс пространства имён `width`, `placeholder`, `tokens` и `i18n`, которые класс объявляет сам.

Обновлено 7 окт. 2026 г. [Редактировать на GitHub](https://github.com/JackUait/blok/blob/main/docs/src/components/api/api-data.ts)

### Как получить экземпляр редактора

Методы ниже вызываются на редакторе, созданном через new Blok(). Они доступны после того, как разрешится editor.isReady.

TypeScript

```
// You already hold the instance returned by the constructor.
const editor = new Blok({ holder: 'editor' });
await editor.isReady;

// Call any API method on it.
editor.caret.setToLastBlock('end');
```

## Методы

### save()

Promise<OutputData>

Извлекает текущее содержимое редактора в виде структурированных JSON-данных. Это основной метод для сохранения содержимого редактора.

Поля с форматированным текстом, например `paragraph.text`, хранят фрагменты: массивы `{ text, marks? }`. Документ, сохранённый старой версией, может хранить HTML-строки, пока его не сохранят снова. `migrateToRichText` переводит его.

Когда использовать

Вызывайте его после `await editor.isReady`. Возвращённый JSON и есть ваш источник истины. Сохраните его и передайте обратно в `render()`.

Ошибки

- Редактор находится в режиме только для чтения в момент вызова save(). Blok's content can not be saved in read-only mode Вызовите `readOnly.set(false)` перед сохранением. Ещё можно сохранить данные из последнего вызова `onSave` или из собственного зеркального состояния.

TypeScript

```
// Save editor content
const data = await editor.save();
console.log(data.blocks); // Array of block data
```

### render(data)

Promise<void>

Отображает содержимое редактора из ранее сохранённых JSON-данных. Принимает нестрогий формат (`LooseOutputData`). Значение `null` для `data`, `id` или `time` блока из backend-DTO нормализуется на границе.

Когда использовать

Загружает сохранённый контент и заменяет текущий документ. Чтобы добавить контент, а не заменить, используйте `blocks.insertMany()`.

TypeScript

```
// Load saved content
const savedData = {
  blocks: [
    { id: '1', type: 'paragraph', data: { text: 'Hello' } }
  ]
};
await editor.render(savedData);
```

### focus(atEnd?)

boolean

Устанавливает фокус на редактор. Может также поставить курсор в конец содержимого.

Когда использовать

Передайте `true`, чтобы поставить курсор в самый конец. Для конкретного блока или смещения используйте API `caret`.

TypeScript

```
// Focus at start
editor.focus();

// Focus at end
editor.focus(true);
```

### clear()

Promise<void>

Удаляет всё содержимое редактора. Остаётся один пустой блок инструмента по умолчанию, поэтому редактор никогда не бывает без блоков. При этом следующий вызов save() всё равно вернёт `blocks: []`. Пустой блок по умолчанию не проходит валидацию и отбрасывается из результата.

Когда использовать

Удаляет все блоки и оставляет один пустой параграф. Это действие можно отменить, в отличие от `destroy()`, который уничтожает экземпляр.

TypeScript

```
// Clear all content
await editor.clear();
```

### destroy()

void

Уничтожает экземпляр редактора и удаляет все DOM-элементы и обработчики событий.

Когда использовать

Вызывайте его из хука размонтирования вашего фреймворка, чтобы не утекли слушатели. После этого экземпляр использовать нельзя. Создайте новый `Blok`, чтобы начать заново.

TypeScript

```
// Clean up on component unmount
editor.destroy();
```

### handlers.set(handlers)

void

Устанавливает, заменяет или удаляет живые колбэки редактора на месте: `onChange`, `onSave`, `onEnter`, `onSubmit`, `onBeforeRender`, `onAfterRender`. Замена идёт на месте, поэтому курсор, выделение, прокрутка и история отмен сохраняются.

Затрагиваются только переданные ключи. Ключ со значением `undefined` СНИМАЕТ обработчик. Это важно, потому что само наличие колбэка задаёт поведение.

- С `onSubmit` клавиша Enter выполняет сериализацию и отправку вместо разбиения блока.
- С `onSave` включается конвейер отслеживания изменений.

Используйте метод, чтобы сделать колбэк реактивным без пересоздания редактора. Адаптеры React, Vue и Angular вызывают этот сеттер за вас, когда prop, слушатель или колбэк из `[config]` появляется или исчезает.

Когда использовать

Затрагиваются только переданные ключи. Ключ со значением `undefined` снимает обработчик. Именно так режим «Enter отправляет» выключается обратно.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `handlers` | `LiveHandlers` | Обязательный | — | Частичная карта живых колбэков. Пропущенные ключи остаются как есть. Ключ со значением `undefined` снимает обработчик. |

TypeScript

```
// "Enter sends" while composing, default Enter while editing a draft
editor.handlers.set({
  onSubmit: sendsOnEnter ? (data) => send(data) : undefined,
});

// Start mirroring content into your store, later stop again
editor.handlers.set({ onSave: (data) => store.set(data) });
editor.handlers.set({ onSave: undefined });
```

### whenAllReady(options?)

Promise<void>

Статический метод. Он резолвится, когда каждый экземпляр Blok в заданной области завершил загрузку, то есть его `isReady` завершился. Отклонение тоже считается завершением. Это общий сигнал готовности для страниц с несколькими экземплярами, он заменяет ручную сборку колбэков `onReady` по каждому экземпляру.

- Передайте `within` (Element), чтобы учитывать только экземпляры внутри вашего поддерева.
  - Тогда посторонний редактор на странице не сможет держать проверку закрытой.
- Передайте `settleOn: 'rendered'`, чтобы готовность означала не конец конструктора, а появление контента в DOM. Это покрывает и повторные рендеры через `render(data)` после загрузки.

Пустая область резолвится сразу. Экземпляры, появившиеся пока промис в ожидании, продлевают ожидание. Экземпляры, созданные после его резолва, не учитываются: вызовите метод снова или используйте `subscribeReady()` для живого сигнала.

Когда использовать

Вызывайте как `Blok.whenAllReady()` на классе, а не на экземпляре. Экземпляр, который ещё загружается, учитывается в любой области, даже если его обёртка ещё не добавлена в документ. Лишнее ожидание безопасно. Недостаточное является ошибкой.

TypeScript

```
// A comments list: N read-only bodies + a composer.
// Wait only for the editors inside this list.
await Blok.whenAllReady({
  within: listElement,
  settleOn: 'rendered',
});
composer.focus();
```

### readyState(options?)

{ total: number; pending: number; ready: boolean }

Статический метод. Он даёт синхронный снимок готовности для области.

Снимок показывает, сколько экземпляров попадает в `within`. Он также показывает, сколько из них ещё не готовы на запрошенном уровне `settleOn` и готова ли область целиком. Пустая область возвращает `ready: true`, поэтому отдельная проверка «ждать нечего» не нужна.

Когда использовать

Метод достаточно дёшев, чтобы вызывать его на каждое уведомление из `subscribeReady()`. Он обходит зарегистрированные экземпляры и проверяет вложенность в DOM.

TypeScript

```
const { pending, ready } = Blok.readyState({ within: listElement });

if (!ready) {
  showSkeleton(pending);
}
```

### subscribeReady(listener)

() => void

Статический метод. Он подписывается на изменения готовности всех экземпляров (создание, загрузка, смена состояния рендера, уничтожение) и возвращает функцию отписки. Слушатель вызывается без аргументов, поэтому перечитывайте `Blok.readyState(scope)`, когда он сработает. Подходит для `useSyncExternalStore` и других адаптеров хранилищ и даёт живой сигнал вместо одноразовой защёлки.

Когда использовать

Во фреймворках лучше использовать обёртки адаптеров: `useBlokReady()` в @bloklabs/react и @bloklabs/vue, `injectBlokReady()` в @bloklabs/angular. Они оборачивают эту подписку и поиск области.

TypeScript

```
const unsubscribe = Blok.subscribeReady(() => {
  setReady(Blok.readyState({ within: listElement }).ready);
});

// later
unsubscribe();
```

### createSelector(attr, value?)

string

Именованный экспорт корня пакета, а не член класса Blok. Строит CSS-селектор по значению `DATA_ATTR`.

- Без `value` получается селектор по наличию атрибута.
- Со значением получается селектор по равенству.

Используйте его вместе с `Blok.DATA_ATTR` вместо поиска по внутренним именам классов Blok, которые не входят в публичную поверхность.

TypeScript

```
import { DATA_ATTR, createSelector } from '@bloklabs/core';

createSelector(DATA_ATTR.element); // '[data-blok-element]'
document.querySelectorAll(createSelector(DATA_ATTR.selected, true));
```

### icons

string

Именованные экспорты подпути `@bloklabs/core/icons`, а не члены класса Blok. Это собственные глифы Blok в виде SVG-строк, по одной константе `Icon*` на глиф (`IconBold`, `IconPlus`, `IconTrash`, `IconWarning`, …).

Это обычные строки, поэтому они подставляются прямо туда, где инструмент обязан отдать разметку: в иконку `static get toolbox()` инструмента и в элементы, которые возвращает `renderSettings()`. Подпуть поставляется со сгенерированным самодостаточным файлом деклараций (`types/icons.d.ts`), где перечислены все константы. Полный набор смотрите в автодополнении редактора кода.

TypeScript

```
import { IconBold, IconPlus } from '@bloklabs/core/icons';

class Callout {
  static get toolbox() {
    return { title: 'Callout', icon: IconPlus };
  }

  renderSettings() {
    return [{ icon: IconBold, title: 'Bold text', onActivate: () => this.toggleBold() }];
  }
}
```

## Свойства

| Свойство | Тип | Описание |
| --- | --- | --- |
| `DATA_ATTR` | `Record<DataAttrKey, DataAttrValue>` | Именованный экспорт корня пакета (`import { DATA_ATTR } from '@bloklabs/core'`), а не свойство экземпляра редактора. Это стабильные имена атрибутов `data-blok-*`, которые Blok пишет в своём DOM. Так и следует запрашивать DOM редактора и писать тесты на стороне хоста вместо поиска по внутренним именам классов. Рядом с ним экспортируются типы `DataAttrKey` / `DataAttrValue` и хелпер `createSelector()`. |
| `BLOK_FONT_SIZE_TOKENS` | `BlokFontSizeTokens` | Именованный экспорт корня пакета (`import { BLOK_FONT_SIZE_TOKENS } from '@bloklabs/core'`), а не свойство экземпляра редактора. Он даёт CSS-переменную, которую пишет каждый сценарий `style.fontSize`, в карте ровно той же формы, что и сама конфигурация (`BLOK_FONT_SIZE_TOKENS.paragraph`, `.heading[1]`, `.list.checklist`, `.bookmark.link`, …). Используйте её везде, где типографика задаётся не конфигурацией конструктора, а другим каналом: CSS-правилом для отдельной области или `editor.tokens.set({ [BLOK_FONT_SIZE_TOKENS.paragraph]: '18px' })` в рантайме. Тогда имена CSS-переменных не придётся копировать руками, а переименование станет ошибкой компиляции, а не молчаливым отсутствием эффекта. |
| `version` | `string` | Именованный экспорт корня пакета (`import { version } from '@bloklabs/core'`), а не свойство экземпляра редактора. Это версия работающего редактора, то же значение, которое попадает в `OutputData.version`. |
| `PendingBlok` | `{ isReady; isRendered; destroy(); theme; width; placeholder; tokens; i18n }` | Тип, экспортируемый из корня пакета (`import type { PendingBlok } from '@bloklabs/core'`), а не свойство экземпляра редактора. Это поверхность, которая гарантированно существует синхронно между `new Blok(config)` и разрешением `isReady`. Модульные API Blok (`blocks`, `caret`, `history`, `readOnly`, …) создаются асинхронно, поэтому обращение к ним раньше вернёт `undefined`. `PendingBlok` объявляет только восемь перечисленных здесь членов. Это превращает такое окно в ошибку компиляции вместо `undefined` в рантайме: `const pending: PendingBlok = new Blok(config); const editor = await pending.isReady;`. |
| `isReady` | `Promise<Blok>` | Promise, который разрешается готовым экземпляром редактора. Пространства имён API ниже (`blocks`, `caret`, `history`, `readOnly`, …) создаются асинхронно. До его разрешения они равны `undefined`, поэтому типизируйте ссылку, которой вы владеете в этот момент, как `PendingBlok`. |
| `isRendered` | `boolean` | Синхронный флаг готовности рендера. Он равен true, когда текущая партия рендера попала в DOM, и повторяет атрибут `data-blok-rendered` на обёртке. Он равен false до первого рендера и во время повторного рендера. Флаг дополняет асинхронные `isReady` и `onReady`: не нужны ни await, ни колбэк, поэтому состояние монтирования можно опрашивать синхронно. |
| `blocks` | `Blocks` | Модуль API для работы с блоками |
| `caret` | `Caret` | Модуль API для управления курсором |
| `history` | `History` | Модуль API истории |
| `saver` | `Saver` | Модуль API сохранения |
| `toolbar` | `Toolbar` | Модуль API панели инструментов |
| `inlineToolbar` | `InlineToolbar` | Модуль API строчной панели |
| `tools` | `Tools` | Модуль API инструментов |
| `uploader` | `Uploader` | Модуль API загрузчика: загрузка ассетов с маршрутизацией по виду ассета |
| `events` | `Events` | Модуль API событий |
| `listeners` | `Listeners` | Модуль API слушателей |
| `notifier` | `Notifier` | Модуль API уведомлений |
| `sanitizer` | `Sanitizer` | Модуль API очистки |
| `selection` | `Selection` | Модуль API выделения |
| `marks` | `Marks` | Модуль API меток: операции со строчными метками с учётом диапазона |
| `styles` | `Styles` | Модуль API стилей |
| `tooltip` | `Tooltip` | Модуль API подсказок |
| `readOnly` | `ReadOnly` | Модуль API режима только для чтения |
| `ui` | `Ui` | Модуль API интерфейса |
| `theme` | `Theme` | Модуль API темы |
| `width` | `Width` | Модуль API ширины |
| `placeholder` | `Placeholder` | Модуль API плейсхолдера |
| `tokens` | `Tokens` | Модуль API токенов темы в рантайме |
| `i18n` | `EditorI18n` | Модуль API i18n. Всё, что инструмент получает через `api.i18n`, плюс метод `update()` |
| `config` | `Readonly<Pick<BlokConfig, 'linkPaste' | 'link'>>` | Доступное только для чтения представление отдельных настроек редактора: опции `link` и `linkPaste`, с которыми создан этот экземпляр. Собственный строчный инструмент или инструмент ссылок читает политику ссылок хоста отсюда (как `api.config`), а не выводит её заново. |
| `rectangleSelection` | `{ cancelActiveSelection(): void; isRectActivated(): boolean; clearSelection(): void; startSelection(pageX: number, pageY: number, shiftKey?: boolean): void; endSelection(): void }` | Управление выделением перетаскиванием (рамкой). Доступно также внутри инструмента как `api.rectangleSelection`. `startSelection(pageX, pageY, shiftKey?)` начинает рамку от координат страницы. `endSelection()` сбрасывает состояние перетаскивания и прячет оверлей. `isRectActivated()` сообщает, активна ли рамка сейчас. `clearSelection()` снимает флаг активности. `cancelActiveSelection()` прерывает начатое выделение (clear + end). Его вызывает другая система выделения, например выделение ячеек таблицы, когда она забирает приоритет. |
