Перейти к содержимому
ФреймворкJavaScript

Title API: заголовок страницы и значок

Чтение и изменение заголовка страницы и его значка. Они стоят над первым блоком или в вашем собственном элементе. Заголовок это одна строка простого текста. Оба хранятся в документе и сохраняются в OutputData как title и icon.

Включается опцией pageTitle. editor.title доступен сразу после new Blok(), а вызовы до isReady повторяются, когда редактор готов. Исключение составляет title.focus(): до isReady он ничего не делает.

Опция title: true переносит заголовок через преобразования. Без неё каждое преобразование работает как раньше.

  • blocksToHtml записывает его первым как <h1>, перед которым стоит значок.
  • blocksToMarkdown, blocksToMarkdownWithReport и blocks.exportMarkdown записывают его как заголовок #. Значок-картинка не записывается.
  • blocksToPlainText записывает его первой строкой.
  • markdownToBlocksWithReport и htmlToBlocksWithReport вынимают из блоков ведущий заголовок # или <h1>. Они возвращают его как title и icon. Заголовок, который начинается с эмодзи и пробела, возвращается как значок и заголовок.
    • Заголовок страницы это простой текст, поэтому форматирование в том заголовке теряется. Оба отчёта добавляют об этом предупреждение heading.
    • markdownToBlocks и htmlToBlocks с этой опцией только убирают заголовок.
  • blocks.importMarkdown берёт заголовок и значок редактора из этого заголовка. Заголовок без эмодзи очищает значок, а отсутствие заголовка очищает оба.
  • extractTexts ставит заголовок первым в списке, а injectTexts записывает его обратно оттуда. Все остальные индексы сдвигаются на один. Пустой перевод убирает заголовок.

Известны такие ограничения.

  • Восстановление версии, сохранённой до того, как сервер начал хранить заголовки страниц, очищает текущий заголовок.
  • Совместный редактор, открытый без сети, показывает последние известные блоки, но без заголовка.
  • Хост не может задать заголовок через эндпоинт сервера /edit.
  • Когда двое печатают в заголовке одновременно, побеждает последняя запись.
Обновлено 8 окт. 2026 г.Редактировать на GitHub

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

Методы ниже вызываются на редакторе, созданном через 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');

Методы

title.get()

string

Текущий заголовок. Если его нет, это ''.

TypeScript
console.log(editor.title.get()); // 'Roadmap'

title.set(text, options?)

void

Заменяет заголовок. Делает один шаг отмены и вызывает onChange с источником api. Если заголовок уже такой, ничего не происходит.

Передайте { record: false } для записи без шага отмены, например для переименования из вашего бэкенда. Участники всё равно получают запись, а onChange получает { source: 'api', record: false }.

  • Отмена не уходит дальше этого значения до следующего записанного изменения заголовка. После него отмена может вернуть заголовок, который был до этого значения.
  • Чтобы значение стало нижней границей, вызовите history.clear() сразу после записи.
  • Набор текста, который продолжается после этого, остаётся одним шагом отмены. Отмена возвращает записанное вами значение, а не то, что было до набора.

Параметры

ПараметрТипОбязательныйПо умолчаниюОписание
textstringОбязательный—

Новый заголовок. '' очищает его.

options.recordboolean—true

false: без шага отмены. Участники всё равно получают запись.

TypeScript
editor.title.set('Roadmap 2027');

// A rename from your backend: no undo step
editor.title.set(serverTitle, { record: false });

title.focus(position?)

void

Ставит каретку в заголовок, по умолчанию в конец. Передайте 'start' для начала. Ничего не делает, когда заголовок выключен, и до isReady.

TypeScript
editor.title.focus('start');

title.mount(holder)

void

Переносит заголовок и значок в holder, элемент или селектор. Фокус и каретка сохраняются. null возвращает заголовок над первым блоком.

После isReady селектор, который ничего не находит, бросает ошибку. До isReady вызов ждёт редактор. Плохой селектор тогда пишется в лог, а заголовок остаётся на месте.

Чтобы выровнять ваш собственный раздел между заголовком и редактором, повторите разметку заголовка. Его переменная --blok-content-column задана на собственном элементе заголовка, поэтому соседний раздел её не видит.

  • Задайте разделу отступ в начале, равный полю редактора. По умолчанию это 56px.
    • Оно равно 0 при hideToolbar: true или readOnly: { hideControls: true }.
    • toolbarPosition: 'right' переносит его в конец.
  • Внутри задайте содержимому box-sizing: border-box, max-width: var(--blok-content-max-width, 720px) и padding-inline: var(--blok-block-padding-inline, 2px).
  • В ширине full используйте none вместо 720px.
  • Выравнивайте его так, как задаёт style.contentAlign.
    • Значению по умолчанию 'left' отступ не нужен.
    • 'center' требует margin-inline: auto.
    • 'right' требует margin-inline-start: auto.

Раздел читает эти переменные только у своих предков. Blok применяет style.tokens только к своим элементам, поэтому раздел рядом с заголовком их не видит.

  • Если вы задаёте --blok-content-max-width, объявите её на элементе, который содержит и раздел, и редактор.
  • Иначе раздел возьмёт запасные 720px и съедет относительно заголовка.

С полем всё иначе. Blok объявляет --blok-editor-gutter-start на собственном элементе редактора, поэтому значение на предке до редактора не доходит. style.tokens пропускает переменные поля с предупреждением.

  • Меняйте поле CSS-правилом на редакторе, например [data-blok-interface] { --blok-editor-gutter-start: 20px; }.
  • Раздел это правило не видит. Задайте ему то же значение сами: числом или той же переменной на одном из его собственных предков.
TypeScript
editor.title.mount('#page-title');

// A section of your own between the title and the editor
// .page-meta { box-sizing: border-box; padding-inline-start: 56px; }
// .page-meta > div {
//   box-sizing: border-box;
//   max-width: var(--blok-content-max-width, 720px);
//   padding-inline: var(--blok-block-padding-inline, 2px);
// }

// Back above the first block
editor.title.mount(null);

title.icon.get()

PageIcon | null

Текущий значок: { type: 'emoji', value } или { type: 'image', url }. Если значка нет, это null.

TypeScript
const icon = editor.title.icon.get(); // { type: 'emoji', value: '🗺️' }

title.icon.set(icon, options?)

void

Задаёт значок или убирает его при null. Делает один шаг отмены и вызывает onIconChange с источником api. { record: false } работает так же, как у title.set.

TypeScript
editor.title.icon.set({ type: 'emoji', value: '🚀' });
editor.title.icon.set(null);
TypeScript
import { Blok } from '@bloklabs/core';

const editor = new Blok({
  holder: 'editor',
  pageTitle: {
    placeholder: 'Untitled',
    onChange: (title, change) => {
      if (change.source !== 'remote') {
        saveTitle(title);
      }
    },
  },
  data: { title: 'Roadmap', icon: { type: 'emoji', value: '🗺️' }, blocks: [] },
});

editor.title.get(); // 'Roadmap'

const saved = await editor.save();
// saved.title === 'Roadmap'

Title API

СвойствоОписание
holderHTMLElement | string

Элемент или селектор, в котором рисуется заголовок. Без него заголовок стоит над первым блоком.

placeholderstring

Показывается, пока заголовок пуст. По умолчанию это локализованное сообщение title.placeholder.

iconboolean

false скрывает значок и кнопку добавления значка.

onChange(title: string, change: TitleChange) => void

Вызывается при каждом изменении заголовка, из любого источника. change.source равен user, undo, redo, remote или api. Сохраняйте при user, undo, redo и api.

change.record равен false только для записи с { record: false }. Иначе этого ключа нет.

onIconChange(icon: PageIcon | null, change: TitleChange) => void

Вызывается при каждом изменении значка, из любого источника. null значит, что значок убран. change такой же, как у onChange.