---
title: "BlockAPI — id, name, holder и события блока"
description: "Работа с одним блоком: чтение id и имени, доступ к его DOM-элементу, сохранение и отправка событий инструмента."
source: https://blokeditor.com/ru/docs/block-api/
lastmod: 2026-09-07
---

Фреймворк JavaScript

Основное BlockAPI

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

# BlockAPI: работа с одним блоком

Интерфейс для работы с отдельными блоками. Возвращается методами blocks.getById(), blocks.getBlockByIndex() и blocks.insert().

[Редактировать на 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');
```

## Методы

### block.save()

Promise<void|SavedData>

Сохранить содержимое блока и вернуть его данные.

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

Возвращает данные только этого блока — удобно проверить или сохранить один блок без полного обхода `editor.save()`.

TypeScript

```
const block = editor.blocks.getById('block-123');
const saved = await block.save();
// saved resolves to a SavedData object (or undefined if extraction fails):
// { id: 'block-123', tool: 'paragraph', data: { text: 'Block content' }, time: 1717000000000 }
console.log(saved?.data); // { text: 'Block content' }
```

### block.validate(data)

Promise<boolean>

Проверить данные блока по правилам валидации инструмента.

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

Запускает `validate()` инструмента для переданных данных; используйте, чтобы отсеять пустые или некорректные блоки перед сохранением.

TypeScript

```
const block = editor.blocks.getById('block-123');
const isValid = await block.validate({ text: 'Hello' });
if (!isValid) {
  console.log('Block data is invalid');
}
```

### block.call(methodName, param?)

void

Вызвать собственный метод инструмента блока.

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

Запасной способ вызвать собственный метод инструмента — для поведения вне стандартного API BlockTool.

TypeScript

```
const block = editor.blocks.getById('block-123');
// Call a custom method defined in the tool
block.call('showNotification', { message: 'Hello' });
```

### block.dispatchChange()

void

Вручную вызвать колбэк onChange для этого блока.

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

Вызывайте, когда меняете блок в обход Blok (например, асинхронно), чтобы сработали события изменения и синхронизация CRDT.

TypeScript

```
const block = editor.blocks.getById('block-123');
// Trigger change after invisible modification
block.dispatchChange();
```

### block.getActiveToolboxEntry()

Promise<ToolboxConfigEntry | undefined>

Получить активный пункт тулбокса для этого блока (например, Заголовок 1 или Заголовок 2).

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

Определяет активный вариант в тулбоксе (например, Заголовок 1 или 2) — полезно для отражения состояния в своём UI.

TypeScript

```
const block = editor.blocks.getById('block-123');
const entry = await block.getActiveToolboxEntry();
if (entry) {
  console.log('Active entry:', entry.title);
}
```

### block.getChildren()

BlockAPI[]

Прямые дочерние блоки этого блока как объекты BlockAPI, по порядку. Каждый BlockAPI, который выдаёт редактор, живой, поэтому возвращённые дочерние блоки можно обходить рекурсивно (`child.getChildren()`) и изменять (`child.setParent(...)`, `child.insertChild(...)`).

TypeScript

```
const block = editor.blocks.getById('toggle-123');
block?.getChildren().forEach((child) => console.log(child.id));
```

### block.setParent(parentId)

void

Переподчинить этот блок родителю `parentId` или вернуть его на корневой уровень значением `null`. Проходит через универсальную единую точку ядра `setBlockParent`, поэтому `contentIds` родителя обновляется вместе с `parentId` этого блока.

TypeScript

```
const block = editor.blocks.getById('block-123');
block?.setParent('parent-block-id');

// Back to the root level
block?.setParent(null);
```

### block.insertChild(childData?, position?, toolName?, options?)

BlockAPI

Вставить дочерний блок под ЭТОТ блок атомарно — создание и назначение родителя укладываются в один шаг отмены (делегирует в `blocks.insertInsideParent`). `position` — это `BlockChildPosition`: 'start' | 'end' | { before: childId } | { after: childId }, по умолчанию 'end' (добавляется в конец, за всё поддерево). `toolName` выбирает блочный инструмент дочернего блока и по умолчанию равен `config.defaultBlock`, поэтому ТИПИЗИРОВАННЫЙ дочерний блок — это одна операция вместо вставки с последующим переподчинением; инструмент, ограниченный внутри ячеек таблицы, понижается до блока по умолчанию, когда новый дочерний блок попал бы внутрь такой ячейки. `childData` по умолчанию равен `{ text: '' }` для блока по умолчанию и `{}`, когда `toolName` называет другой инструмент. `options` несёт тот же словарь `{ focus, caret, id, tunes, replace }`, что и расширенная спецификация `insert` у адаптеров фреймворков, поэтому контейнерному инструменту никогда не приходится вручную расставлять курсор или следом вызывать `update`, чтобы применить тюны.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `childData` | `BlockToolData` | — | `{ text: '' } / {}` | Данные для нового дочернего блока. По умолчанию — пустой объект данных параграфа для блочного инструмента по умолчанию и {} — что позволяет инструменту применить собственные значения по умолчанию — когда указан toolName. |
| `position` | `BlockChildPosition` | — | `'end'` | Куда среди существующих дочерних блоков вставлять: 'start', 'end', { before: childId } или { after: childId }. |
| `toolName` | `string` | — | `config.defaultBlock` | Блочный инструмент, который нужно создать для дочернего блока. Понижается до блока по умолчанию, когда он ограничен внутри ячеек таблицы и новый дочерний блок попал бы внутрь такой ячейки. |
| `options` | `InsertChildOptions` | — | `{}` | focus — сделать новый дочерний блок текущим. caret — поставить курсор внутрь него ({ position?, offset? }), применяется, только когда дочерний блок действительно создан. id — явный id; уже существующий id работает как «вставить, если нет» (возвращается этот дочерний блок, ничего не создаётся). tunes — данные тюнов блока, применяемые при создании. replace — перезаписать дочерний блок, названный объектной позицией, вместо вставки рядом с ним; с 'start'/'end' перезаписывать нечего, и вызов выбрасывает исключение. |

TypeScript

```
const block = editor.blocks.getById('toggle-123');
const child = block?.insertChild({ text: 'Hidden content' });

// Place it among the existing children instead of appending
block?.insertChild({ text: 'First' }, 'start');
block?.insertChild({ text: 'After that one' }, { after: 'child-id' });

// A typed child, in a single undo entry
block?.insertChild({ text: 'Section', level: 3 }, 'end', 'header');

// Drop the caret into the new child at a specific offset
block?.insertChild({ text: 'Draft' }, 'end', undefined, { caret: { offset: 5 } });

// Idempotent: a re-running effect cannot duplicate this child
block?.insertChild({ text: 'Intro' }, 'start', undefined, { id: 'intro-row' });

// Child-level "turn into" — overwrite an existing child, keeping it parented
block?.insertChild({ text: 'Now a heading', level: 3 }, { before: 'child-id' }, 'header', { replace: true });
```

### block.moveChild(childId, delta)

void

Переместить прямой дочерний блок на `delta` позиций среди его соседей, с ограничением по допустимому диапазону. Дочерний блок со своим поддеревом встаёт за потомками целевого соседа, а не внутрь них. No-op, когда `delta` равна 0, когда `childId` не является прямым дочерним блоком или когда ограниченное перемещение не изменит позицию.

TypeScript

```
const block = editor.blocks.getById('toggle-123');
block?.moveChild('child-id', -1); // one position toward the start
block?.moveChild('child-id', 1);  // one position toward the end
```

## Свойства

| Свойство | Тип | Описание |
| --- | --- | --- |
| `id` | `string` | Уникальный идентификатор блока |
| `name` | `string` | Имя инструмента (например, «paragraph», «header») |
| `config` | `ToolConfig` | Конфигурация инструмента, переданная при инициализации |
| `holder` | `HTMLElement` | Обёртка HTML-элемента инструмента |
| `isEmpty` | `boolean` | True, если содержимое блока пусто |
| `selected` | `boolean` | True, если блок входит в выбор на уровне БЛОКОВ (перетаскивание рамкой, Shift+Click, Shift+Arrow, Cmd/Ctrl+A). Перетаскивание по тексту нескольких блоков даёт вместо этого выделение на уровне символов, при котором ни один блок не помечен как выбранный — такое выделение читайте из собственного Selection документа. |
| `focusable` | `boolean` | True, если у блока есть поля ввода, которые можно сфокусировать |
| `stretched` | `boolean` | Геттер/сеттер состояния растягивания блока |
| `parentId` | `string | null` | Id родительского блока или null, если у этого блока нет родителя |
| `contentIds` | `readonly string[]` | Id прямых дочерних блоков этого блока, по порядку — копия только для чтения, поэтому её изменение ничего не даёт. Аналог parentId на уровне блока: позволяет контейнерному инструменту читать свои дочерние блоки, не обращаясь к API редактора |
| `preservedData` | `BlockToolData` | Последние успешно извлечённые данные блочного инструмента, синхронно — полезно, когда асинхронный save() неприменим, например при операциях с буфером обмена |
| `preservedTunes` | `{ [name: string]: BlockTuneData }` | Последние успешно извлечённые данные тюнов блока, синхронно — полезно, когда асинхронный save() неприменим, например при операциях с буфером обмена |
