Как создать первый блок Gutenberg с @wordpress/scripts: пошаговая инструкция
24 апреля 2026
Разработка блоков для Gutenberg традиционно считается сложной задачей, особенно для тех, кто только начинает работать с WordPress. Официальная документация обширна, и легко потеряться в ней ещё до того, как напишешь первую строку кода. Многие разработчики тратят целый день на настройку Webpack, а затем просто сдаются.
Но есть хорошая новость: в 2026 году всё стало намного проще. Вам больше не нужно самостоятельно настраивать Webpack или разбираться в сложных конфигурациях сборки. Пакет @wordpress/scripts берёт на себя всю работу с инструментами сборки, а block.json упрощает регистрацию блоков до предела.
Это руководство покажет вам современный подход к разработке блоков Gutenberg — подход, который действительно прост и понятен. Вы научитесь создавать свой первый блок с нуля, поймёте структуру файлов, освоите работу с атрибутами и стилями, и узнаете, как избежать типичных ошибок, которые допускают начинающие разработчики.
Необходимые условия
Перед началом работы подготовьте:
- Node.js версии 18 или выше и пакетный менеджер npm
- Локальную среду разработки WordPress (Local by Flywheel, WP-CLI или WordPress Playground)
Docker, Vagrant и ручная настройка Webpack не нужны — @wordpress/scripts берёт это на себя.
Запуск проекта через @wordpress/create-block
Официальный генератор блоков создаст готовую структуру плагина. Откройте терминал и выполните:
cd wp-content/plugins
npx @wordpress/create-block my-first-block --namespace myfirstblock
После генерации вы получите:
my-first-block/
├── my-first-block.php # Заголовок плагина + регистрация блока
├── package.json # Зависимости и скрипты сборки
├── src/
│ ├── block.json # Метаданные блока
│ ├── edit.js # Компонент редактора
│ ├── save.js # Фронтенд-разметка
│ ├── index.js # Точка входа JavaScript
│ └── style.scss # Стили для фронтенда
└── build/ # Скомпилированные файлы (автогенерация)
Активируйте плагин в админке WordPress и запустите режим разработки:
cd my-first-block
npm start
Файлы из папки src/ будут компилироваться автоматически при сохранении. Блок появится в редакторе в категории «Виджеты».
Конфигурация block.json
Файл block.json содержит метаданные блока: имя, атрибуты, настройки боковой панели, пути к скриптам и стилям. WordPress читает его напрямую — отдельная регистрация в PHP не требуется.
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "myfirstblock/notice",
"version": "1.0.0",
"title": "Notice",
"category": "text",
"icon": "info",
"description": "A simple notice block with a message and colour option.",
"attributes": {
"message": {
"type": "string",
"source": "html",
"selector": "p"
},
"backgroundColor": {
"type": "string",
"default": "#f0f4ff"
}
},
"supports": {
"html": false,
"align": true,
"color": {
"background": true,
"text": true
},
"typography": {
"fontSize": true
}
},
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
На что обратить внимание:
name— уникальный идентификатор в форматепространство-имён/название-блока, только нижний регистрattributes— структура данных блока и способ их сериализации в HTMLsupports— доступные параметры в интерфейсе редактора (выравнивание, цвет, типографика)
Разница между edit.js и save.js
edit.js — интерфейс редактора
Компонент отвечает за отображение блока внутри админки. Это React-компонент, но подключать React отдельно не нужно — библиотека доступна глобально.
import { useBlockProps, RichText, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ColorPicker } from '@wordpress/components';
export default function Edit( { attributes, setAttributes } ) {
const { message, backgroundColor } = attributes;
const blockProps = useBlockProps( {
style: { backgroundColor },
} );
return (
<>
<InspectorControls>
<PanelBody title="Background colour" initialOpen={ true }>
<ColorPicker
color={ backgroundColor }
onChangeComplete={ ( value ) => setAttributes( { backgroundColor: value.hex } ) }
/>
</PanelBody>
</InspectorControls>
<div { ...blockProps }>
<RichText
tagName="p"
value={ message }
onChange={ ( value ) => setAttributes( { message: value } ) }
placeholder="Write your notice here..."
/>
</div>
</>
);
}
save.js — фронтенд-разметка
Этот файл генерирует статический HTML, который сохраняется в базу данных при публикации поста. Рендеринг происходит один раз — при сохранении, а не при каждой загрузке страницы.
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function Save( { attributes } ) {
const { message, backgroundColor } = attributes;
const blockProps = useBlockProps.save( {
style: { backgroundColor },
} );
return (
<div { ...blockProps }>
<RichText.Content tagName="p" value={ message } />
</div>
);
}
Регистрация в PHP
Файл плагина остаётся минималистичным. Функция register_block_type считывает block.json из папки build/ и регистрирует блок автоматически.
<?php
/**
* Plugin Name: My First Block
* Plugin URI: https://kamalhosen.com
* Description: A simple custom Gutenberg block.
* Version: 1.0.0
* License: GPL-2.0-or-later
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_action( 'init', function() {
register_block_type( __DIR__ . '/build' );
} );
Статические и динамические блоки
Статические блоки хранят готовый HTML в базе данных. Подходят для контента, который не меняется после публикации.
Динамические блоки рендерятся через PHP при каждом запросе страницы. Используйте, если вывод зависит от актуальных данных (последние посты, виджеты, форма обратной связи).
Для создания динамического блока:
- В
save.jsвернитеnull - Добавьте параметр
render_callbackпри регистрации в PHP
add_action( 'init', function() {
register_block_type( __DIR__ . '/build', [
'render_callback' => 'myfirstblock_render_notice',
] );
} );
function myfirstblock_render_notice( array $attributes, string $content ): string {
$message = wp_kses_post( $attributes['message'] ?? '' );
$bg_color = sanitize_hex_color( $attributes['backgroundColor'] ?? '#f0f4ff' );
return sprintf(
'<div style="background-color: %s;">%s</div>',
esc_attr( $bg_color ),
$message
);
}
Основные пакеты @wordpress
@wordpress/block-editor— хуки и компоненты редактора:useBlockProps,RichText,InspectorControls, инструменты работы с цветом и выравниванием@wordpress/components— UI-элементы:PanelBody,TextControl,ToggleControl,Button,ColorPicker@wordpress/data— доступ к хранилищу данных редактора (текущий пост, настройки, выделенный блок)@wordpress/i18n— локализация: функция__( 'строка', 'текстовое-домен' )для переводов интерфейса@wordpress/api-fetch— запросы к REST API WordPress с встроенной аутентификацией и обработкой ошибок@wordpress/hooks— система хуков для JavaScript:addFilter,addAction,doAction
Типичные проблемы и решения
Ошибки валидации блока
При изменении save.js WordPress покажет ошибку валидации для постов, где блок уже использовался. Варианты решения:
- Использовать динамический блок с
render_callback— структура генерируется на лету, валидация не требуется - Добавить
deprecated-версии вblock.json— для обратной совместимости старой разметки - Изменить имя блока в
block.json— подходит на этапе разработки, старые блоки останутся как есть
Категории блоков
В поле category укажите одно из стандартных значений: text, media, design, widgets, theme, embed.
Для собственной категории добавьте фильтр в PHP:
add_filter( 'block_categories_all', function( array $categories ): array {
return array_merge( $categories, [
[
'slug' => 'my-plugin',
'title' => 'My Plugin',
'icon' => null,
],
] );
} );
Проверка на фронтенде
После добавления блока в пост опубликуйте материал и откройте страницу в режиме инкогнито. Фронтенд загружает скомпилированный style-index.css и результат работы render_callback (если блок динамический) — не файлы редактора.
Если в админке блок отображается корректно, а на сайте — нет, проверьте:
- Совпадают ли классы и структура в
save.jsи PHP-рендерере - Подключаются ли стили из папки
build/ - Нет ли кэша браузера или плагина кэширования


