Introduction to Gutenberg Blocks: Registering Your First Block
Learn to register Gutenberg blocks using PHP, enqueue essential assets, and define attributes to extend your Knowledge Base plugin with custom UI components.
Previously in this course, we covered Building Shortcodes to allow users to embed dynamic content. While shortcodes are functional, they are opaque to the user. This lesson introduces Gutenberg blocks, the modern, interactive way to surface your Knowledge Base content directly within the block editor.
Understanding the Block Architecture
A block in WordPress consists of two distinct worlds: the server-side registration (PHP) and the client-side representation (React/JavaScript).
When you register a block in PHP, you aren't just telling WordPress "this block exists." You are providing a configuration schema that defines how the editor should handle the block's attributes—the data that persists in the post content—and where to find the JavaScript files that define the block's UI.
Registering a Block via PHP
To register a block, we use the register_block_type function. In our MVC-structured plugin, you should place this logic within your plugin's initialization class.
PHP#6A9955">// Inside your plugin's initialization method public function register_kb_blocks() { register_block_type( __DIR__ . '/build/kb-article-block', [ 'attributes' => [ 'articleId' => [ 'type' => 'number', ], 'layout' => [ 'type' => 'string', 'default' => 'list', ], ], 'render_callback' => [$this, 'render_kb_block_content'], ]); }
The first argument is the path to your block.json file. This is the modern standard for block registration. It keeps your metadata (name, title, category, and attributes) decoupled from your logic.
Enqueuing Block Assets
Unlike standard scripts, blocks require specific assets to be loaded only when the block is present in the editor. We handle this by defining editorScript, script, and style keys within your block.json file.
WordPress automatically handles the dependencies for you. If your block relies on @wordpress/blocks or @wordpress/element, WordPress will enqueue them automatically if you use the generated asset.php file from the @wordpress/scripts package.
JSON{ "apiVersion": 2, "name": "kb-plugin/article-block", "title": "Knowledge Base Article", "category": "widgets", "attributes": { "articleId": { "type": "number" } }, "editorScript": "file:./index.js", "editorStyle": "file:./index.css" }
Defining Block Attributes
Attributes are the data properties of your block. If you are building a "Featured Article" block for your Knowledge Base, you need to store the articleId so the block knows which post to fetch.
Attributes are defined in the schema. When the block saves, these attributes are serialized into the HTML comment wrapper:
<!-- wp:kb-plugin/article-block {"articleId":123} /-->
Because we are working within the block editor, you'll need to understand Introduction to React State: Making Your UI Interactive to manage the changes to these attributes when a user interacts with your block settings.
Hands-on Exercise: Register a Placeholder Block
- Create a directory inside your plugin folder named
blocks/kb-article. - Create a
block.jsonfile inside that folder with a unique name and title. - In your main plugin class, add an action hook to
initthat callsregister_block_typepointing to yourblock.jsonfile. - Verify the block appears in the editor inserter by typing
/and the name of your block.
Common Pitfalls
- Forgetting
apiVersion: Always setapiVersionto2in yourblock.json. It enables the modern block transformation and rendering APIs. - Hardcoding Paths: Use
__DIR__to define paths to your block folders. Hardcoded strings will break when users install your plugin in different directory structures. - Mixing Logic: Don't put business logic inside the block's
render_callback. Keep that logic in your Model layer, as discussed in The Model Layer for Data, and call it from the callback. - Asset Dependencies: If your
index.jsuses React, ensure you have correctly configured your build process to generate the dependency array so WordPress knows to load the React library.
Recap
We've moved from static shortcodes to dynamic blocks. By registering blocks via block.json, we establish a clean, predictable contract between the WordPress editor and our plugin's data. Remember that while PHP handles the registration and server-side rendering, the actual "magic" of the editor interface relies on React components.
Up next: We will dive into the Settings API to give users a dedicated admin panel for configuring plugin-wide defaults.
Work with me

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard — by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.

Custom WordPress Theme Development
A custom WordPress theme built exactly to your design — fast, clean, and easy to manage. No bloated page builders, no compromises.