FIFA WORLDCUP OFFER : 50% Off On ALL ITEMS Get It Now >

WordPress Plugin Gutenberg Blocks: How to Build Custom Blocks

WordPress Plugin Gutenberg Blocks: How to Build Custom Blocks

WordPress Plugin Gutenberg Blocks: How to Build Custom Blocks

Introduction

The WordPress Block Editor has changed the way content is created and managed.

Instead of building pages from a single editor field, users can assemble content from individual blocks such as:

Paragraphs

Images

Buttons

Columns

Galleries

Tables

Quotes

Plugins can extend this system by creating their own custom blocks.

A custom block can provide functionality that standard WordPress blocks do not offer.

For example, a plugin could create:

Custom Block ├── Product Showcase ├── Pricing Table ├── Testimonial ├── Analytics Widget ├── FAQ ├── AI Content Assistant ├── WooCommerce Product Grid └── Lead Form

A modern block architecture can look like:

WordPress   ↓ Block Editor   ↓ Custom Block   ↓ Block Attributes   ↓ React Editor UI   ↓ Saved / Rendered Content

For more advanced blocks:

Editor   ↓ Block   ↓ REST API / PHP   ↓ Plugin Service   ↓ Database / External API

Building a custom Gutenberg block involves more than writing JavaScript.

A production-ready block should consider:

block.json

Block registration

Editor controls

Attributes

React

PHP rendering

Dynamic data

Frontend assets

Block supports

Serialization

REST APIs

Security

Accessibility

Internationalization

Performance

Compatibility

In this guide, you'll learn how Gutenberg blocks work, how to create custom blocks inside a WordPress plugin, how block.json works, how to use React in the editor, how to create static and dynamic blocks, how to add controls and attributes, how to connect blocks with WooCommerce and APIs, how to secure dynamic data, how to style blocks, how to test them, and how ThemeKaddora can build reusable block-based products.

What Is a Gutenberg Block?

A Gutenberg block is a modular piece of content or functionality used by the WordPress Block Editor.

Examples include:

Paragraph Image Button Gallery Heading

Plugins can add their own blocks to this system.

For example:

ThemeKaddora Product Block

could allow users to select a product and display it inside a page.

Why Build Custom Gutenberg Blocks?

Custom blocks can help plugins provide:

Better editing experiences

Reusable layouts

Structured content

Dynamic data

Custom business functionality

Visual configuration

WooCommerce features

Interactive components

Blocks can make complex plugin functionality easier for non-technical WordPress users.

Gutenberg Block vs Shortcode

Both can add dynamic functionality, but they work differently.

Shortcode

[product_grid]

Block

Product Grid Block

The block provides a visual editor experience.

Users can configure options directly in the editor instead of memorizing shortcode attributes.

When Should You Use a Block?

Blocks are especially useful when users need to configure:

Layout

Content

Images

Products

Tables

Filters

Visual elements

Dynamic widgets

A shortcode may still be simpler for very small pieces of functionality.

What Is block.json?

block.json is the standard metadata format for describing a WordPress block.

It can define:

Block name

Title

Description

Category

Attributes

Editor script

Styles

Supports

Render file

A simplified example:

{  "apiVersion": 3,  "name": "kdr/product-card",  "title": "Product Card",  "category": "widgets",  "editorScript": "file:./index.js" }

The actual configuration depends on the block.

Why block.json Matters

Block metadata gives WordPress structured information about the block.

Instead of manually registering every asset and setting individually, the metadata file can describe the block's requirements in one place.

This improves consistency and maintainability.

Use a Unique Block Name

A block name generally follows:

namespace/block-name

For example:

kdr/product-card kdr/analytics-widget kdr/faq

The namespace should be unique to your plugin or product.

Avoid generic block names.

Block Directory Structure

A plugin may use:

kdr-blocks/ ├── kdr-blocks.php ├── src/ │   └── blocks/ │       └── product-card/ │           ├── block.json │           ├── index.js │           ├── edit.js │           ├── save.js │           └── style.css ├── build/ └── assets/

The exact structure depends on the chosen build architecture.

Registering Blocks From a Plugin

A plugin can register its blocks using WordPress's block registration APIs.

A common architecture is:

Plugin ↓ Block Registration ↓ block.json ↓ Editor + Frontend Assets

For modern plugins, metadata-based registration is generally preferable to manually duplicating block configuration throughout PHP.

Static vs Dynamic Blocks

One of the most important decisions is whether a block should store its final markup in post content or render dynamically.

Static Block

The block saves markup into the post content.

Editor ↓ Save ↓ Stored Block HTML

Dynamic Block

The block stores attributes while PHP generates the frontend output.

Editor ↓ Attributes ↓ PHP Render ↓ Frontend HTML

When to Use a Static Block

Static blocks are useful when content is primarily user-controlled.

Examples:

Simple testimonial

Styled heading

Button group

Decorative content

Static layout components

The saved markup can be sufficient.

When to Use a Dynamic Block

Dynamic blocks are useful when content changes independently of the post.

Examples:

Product data

Live analytics

Latest posts

Customer information

Stock status

Current pricing

API data

For example:

Product Block ↓ Product ID Stored ↓ Current Product Data Retrieved ↓ Frontend Render

This means the block can reflect updated product information without users editing every post.

Dynamic Block Architecture

A dynamic block can look like:

Editor ↓ Select Product ↓ Store Product ID ↓ Save Post ↓ Frontend Request ↓ PHP Render Callback ↓ WooCommerce ↓ Output

Block Attributes

Attributes store block configuration.

For example:

{  "attributes": {    "productId": {      "type": "number"    },    "showPrice": {      "type": "boolean",      "default": true    }  } }

This allows the block to preserve its settings.

Keep Attributes Minimal

Don't store unnecessary data inside the post.

Instead of storing an entire product object:

productName price stock description images ...

store:

productId

Then retrieve current product information when rendering.

Attributes vs Content

Attributes should represent configuration.

For example:

productId layout showPrice columns

Content belongs in appropriate editable fields or inner blocks.

Don't use one giant JSON attribute to store the entire block state without a clear reason.

Block Editor Interface

The editor can provide controls such as:

Product Select Product Display ☑ Show Price ☑ Show Image Layout Columns: 3 Style Background Typography

The editor experience should remain intuitive.

Use InspectorControls

WordPress block development provides editor-side controls that can appear in the sidebar.

This allows users to configure:

Toggle settings

Select fields

Number controls

Color controls

Spacing

Typography

Use standard WordPress components where practical.

Block Toolbar Controls

Some settings make more sense directly in the block toolbar.

For example:

Align Bold Link View Mode

Keep the toolbar focused on frequently used controls.

Avoid Too Many Controls

A block with:

50 settings

can become overwhelming.

Ask:

Does the user need this setting during content editing?

If not, it may belong in global plugin settings or automatic behavior.

Block Supports

WordPress provides block supports for capabilities such as:

Alignment

Spacing

Color

Typography

Border

Dimensions

Use built-in supports when they already solve the problem.

This makes the block more compatible with WordPress themes and editor features.

Responsive Block Design

A custom block should behave properly on:

Desktop Tablet Mobile

For example, a product grid might use:

Desktop: 4 columns Tablet: 2 columns Mobile: 1 column

Don't assume the editor preview represents every real-world device.

Block Editor Preview vs Frontend

A block can appear correctly inside the editor and still look different on the frontend.

Test both:

Editor + Frontend

They may use different styles, contexts, or rendering logic.

Editor Styles and Frontend Styles

A block may need:

editor.css style.css

Keep styles appropriate to where they are used.

Avoid loading heavy frontend styles into the entire WordPress admin.

Block Asset Loading

Only load block assets where needed.

A page containing no instance of the block should not automatically receive unnecessary large resources unless the architecture intentionally requires it.

Performance becomes increasingly important when a plugin provides many blocks.

Build Process

Modern Gutenberg blocks commonly use a JavaScript build workflow.

A simplified process is:

Source ↓ npm Dependencies ↓ Build ↓ Compiled Assets ↓ WordPress Block

The production plugin should contain the built assets required for the supported installation method.

React and Gutenberg

The Block Editor uses React-based components.

A block's editing interface can use React to:

Render controls

Manage state

Fetch data

React to changes

Display previews

Developers don't need to build the entire application themselves because WordPress provides block-editor components and packages.

Don't Bundle React Unnecessarily

When developing Gutenberg blocks, understand WordPress's supported dependency system.

Do not blindly bundle another copy of libraries already provided by WordPress when the architecture does not require it.

This can reduce:

Bundle size

Conflicts

Duplicate code

Block Data Fetching

A block may need dynamic data while editing.

For example:

Product Selector ↓ Fetch Products ↓ Display Search Results

REST APIs can provide this data.

Use REST APIs for Block Editor Data

A plugin can expose a secure endpoint:

/wp-json/kdr/v1/products

Then the block editor can retrieve data through the API.

The endpoint must enforce permissions appropriate to the data.

Don't Expose Private Data to the Editor

An editor might need:

Product Name Product ID Price

but may not need:

Customer Password Private Notes Payment Tokens

Only return the fields required by the block.

Product Selector Block

A WooCommerce block can allow:

Search Product ↓ Select Product ↓ Store Product ID ↓ Preview Product

This is usually better than asking the user to manually enter an internal product identifier.

Dynamic WooCommerce Block

For example:

Selected Product: 123 Frontend: Fetch Product 123 ↓ Get Current Price ↓ Get Current Stock ↓ Render

The block stays synchronized with actual store data.

Never Trust Stored IDs Blindly

Even though the block stores an ID in post content, the frontend should still verify:

Does the product exist? Is it published? Is it accessible? Should it be displayed?

Content can be changed, imported, or manipulated.

Block Permissions

Some blocks may expose private or user-specific content.

For example:

Customer Dashboard Block

The frontend must check user authorization before rendering sensitive information.

A block's presence in post content is not proof of permission.

Block Security

A secure block should consider:

User Input ↓ Validation ↓ Authorization ↓ Data Access ↓ Escaped Output

Dynamic rendering should follow the same security principles as every other WordPress feature.

Escaping Dynamic Block Output

If PHP renders dynamic data:

Escape HTML

Escape attributes

Escape URLs

Sanitize allowed HTML where appropriate

Don't assume WordPress database data is automatically safe for every output context.

Block HTML and User-Generated Content

Some blocks intentionally allow HTML-like content.

Use appropriate WordPress APIs rather than simply allowing arbitrary HTML.

The correct approach depends on the content model and the user's permissions.

Inner Blocks

Gutenberg allows blocks to contain other blocks.

For example:

Pricing Block ├── Heading ├── Paragraph ├── Button └── Feature List

Inner blocks can make a custom block much more flexible.

When to Use Inner Blocks

Use inner blocks when users should be able to build content compositionally.

Examples:

Hero sections

Pricing cards

Feature sections

Layout containers

Marketing components

Don't Rebuild Standard WordPress Blocks

If WordPress already provides:

Heading Paragraph Button Image Columns

consider using them through inner blocks rather than duplicating their functionality.

This makes your block more compatible with the WordPress ecosystem.

Block Templates

A plugin can define an initial block structure.

For example:

Product Showcase ├── Heading ├── Product Grid └── Button

This can help users start with a useful layout.

Block Patterns

Block patterns can be useful when the goal is primarily a reusable design rather than a new dynamic functionality.

For example:

Testimonials Section Pricing Section Feature Comparison

Use a custom block when the component requires application logic.

Block Variations

One base block can have different variations.

For example:

Product Block ├── Card ├── List └── Compact

Variations can reduce the need to build separate blocks for closely related presentations.

Block Styles

A block can offer style variations:

Default Rounded Minimal Featured

This gives users design flexibility without creating many separate blocks.

Block Naming Strategy

For ThemeKaddora products, use a consistent namespace:

kdr/product-grid kdr/pricing-table kdr/testimonial kdr/ai-assistant

Avoid generic names that could conflict with other plugins.

Multiple Blocks in One Plugin

A plugin may provide:

Kaddora Blocks ├── Product Grid ├── Product Card ├── Pricing Table ├── FAQ ├── Testimonial └── Analytics Widget

Use shared components where appropriate.

Shared React Components

For example:

components/ ├── ProductSelector ├── LoadingState ├── ErrorNotice ├── EmptyState └── SettingsPanel

This reduces duplicated UI code.

Don't Over-Share Components

A shared component should represent a genuinely reusable pattern.

A 50-prop component that behaves differently everywhere may be harder to maintain than two smaller components.

Block Data Stores

Complex blocks may use WordPress data stores to retrieve information.

For example:

Editor ↓ WordPress Data ↓ Entity Records ↓ Block UI

Use established WordPress data APIs where they fit.

Block Editor and REST API Integration

A complex block may rely on:

Block Editor ↓ REST API ↓ Plugin Service ↓ Database

The service layer should remain reusable outside the block when possible.

Dynamic Blocks and Server Rendering

A dynamic block can use a PHP render callback.

Conceptually:

function render_product_block( $attributes ) {    // Retrieve data.    // Validate.    // Return escaped markup. }

Keep this function thin and delegate complex logic to a service.

Don't Put Complex SQL Inside Render Callbacks

Avoid:

Render Block ↓ 200 Lines of SQL ↓ Remote API ↓ Business Logic ↓ HTML

Prefer:

Render Callback ↓ Service ↓ Repository / API ↓ Prepared Data ↓ Markup

Dynamic Blocks and Performance

A block rendered on every page view can execute repeatedly.

Avoid:

Expensive API requests

Large database queries

Rebuilding complex reports

Uncached calculations

Use caching or precomputed data where appropriate.

Cache Dynamic Block Data

For example:

Product Recommendation Block ↓ Check Cache ├── Hit → Use Cached Result └── Miss → Calculate → Store

Choose an appropriate cache lifetime.

Avoid Remote API Calls During Every Render

A block should not do:

Page Load ↓ Call External API ↓ Wait ↓ Render

This can make page performance dependent on an external service.

Use:

Cached data

Background synchronization

Precomputed results

where appropriate.

AI-Powered Gutenberg Blocks

AI plugins can provide blocks such as:

AI Content Assistant AI Product Description AI FAQ AI Recommendation AI Summary

The editor can provide controls:

Topic Tone Length Language

Then the plugin sends the request to the AI service.

Secure AI Block Workflow

Editor ↓ User Request ↓ Permission ↓ Usage Check ↓ Server-Side AI Request ↓ Validate Response ↓ Editor Preview

Never expose provider credentials in browser code.

AI Block Cost Controls

AI block features can generate expensive requests.

Use:

Usage quotas

Request limits

Input-size limits

Model controls

Caching where appropriate

Avoid automatically sending a new AI request on every small editor change.

Example: AI Product Description Block

A user could select:

Product: Premium Headphones Tone: Professional Length: Medium Language: English

The block sends the request to the server and displays the generated draft.

The generated text can then remain editable by the user.

AI Output Should Remain Editable

AI-generated content should not be treated as unquestionable final content.

A good block experience lets users:

Generate ↓ Review ↓ Edit ↓ Save

This is particularly important for product descriptions and marketing content.

Gutenberg Block Accessibility

A custom block should support:

Keyboard navigation

Clear labels

Focus states

Accessible controls

Screen-reader-friendly content

Meaningful error messages

Don't rely only on visual icons.

Block Editor Accessibility

The editor itself provides many accessibility patterns, but custom controls can still introduce problems.

Use WordPress-provided UI components when practical.

Gutenberg Block Internationalization

Every user-facing block string should be translation-ready.

Examples:

Select Product Loading... No Products Found Generate Content

Both PHP and JavaScript should follow WordPress localization practices.

Block Translation and Dynamic Content

Differentiate:

Plugin UI Text

from:

Product Name Customer Content AI-Generated Content

Only interface strings should automatically use the plugin's text domain.

Block Styling

Use plugin-specific classes.

For example:

.kdr-product-card {} .kdr-product-grid {}

Avoid global selectors such as:

.card {} .button {} .container {}

which can conflict with themes and other plugins.

Block Theme Compatibility

The block should work with a reasonable range of WordPress themes.

Avoid assuming:

Specific font families

Fixed container widths

One global color palette

One theme's spacing system

Use WordPress block supports and theme-aware styling where practical.

Editor vs Frontend CSS

The editor may require styles that differ from the frontend.

For example:

Editor: Show Selection Outline Frontend: Hide Editor Controls

Keep these concerns separate.

Block Data Validation

Before rendering:

Attribute ↓ Validate ↓ Normalize ↓ Use

For example:

columns → integer → minimum 1 → maximum allowed

Don't trust serialized block attributes blindly.

Deprecated Block Attributes

As a block evolves, its attribute structure may change.

For example:

Version 1 product Version 2 productId

Use block deprecations and migration strategies where needed.

Block Deprecation

If an older version of a block stored markup differently, WordPress may need a migration path.

A safe process is:

Old Block ↓ Recognize Old Structure ↓ Transform ↓ New Structure

Test existing content after block updates.

Don't Break Existing Posts

One of the biggest Gutenberg mistakes is updating a block in a way that makes existing posts invalid.

Before release, test:

Old Post Content ↓ New Plugin ↓ Block Still Works

Existing content is part of your compatibility contract.

Block Serialization

Static blocks store serialized markup in post content.

Changing:

HTML structure

Attribute names

Wrapper elements

Required markup

can cause validation issues.

Test changes carefully.

Dynamic Blocks and Existing Content

Dynamic blocks generally store attributes rather than complete rendered output.

This can make presentation changes easier because the frontend output can evolve without rewriting every post.

But attribute compatibility still matters.

Gutenberg Block Testing

Test:

Insert Edit Save Reload Duplicate Copy/Paste Update Delete Undo Redo

Also test the frontend.

Test Block Compatibility

Test with:

Different themes

Different screen sizes

WooCommerce

Other blocks

Different WordPress versions

Supported PHP environments

The exact matrix should match the plugin's support policy.

Test Large Block Pages

A page may contain:

1 Block 20 Blocks 100 Blocks

A block that is fast once can become expensive when repeated dozens of times.

Measure editor and frontend performance.

Test Dynamic Block Caching

Verify that repeated blocks don't produce unnecessary duplicate queries or API requests.

For example:

20 Product Blocks

should not necessarily produce:

20 identical external API calls

if the same data can be reused safely.

Test Block Permissions

For blocks displaying private information, test:

Administrator Editor Subscriber Logged-Out Visitor

The rendered result should match the user's authorization.

Test AI Blocks

For AI-powered blocks, test:

Valid Prompt Empty Prompt Large Prompt API Failure Rate Limit Expired Key Unauthorized User Invalid Response

Also verify that provider credentials never reach the browser.

Gutenberg Block Build Testing

Verify the production build contains:

block.json Compiled JavaScript CSS Required Dependencies Translations PHP Render Files

A block that works through the development server may fail after packaging if the build process is incomplete.

Common Gutenberg Block Mistakes

Building Everything as a Custom Block

Use standard blocks, patterns, and variations when they already solve the problem.

Too Many Controls

The editing interface becomes overwhelming.

Storing Entire Objects

Store stable identifiers instead of duplicating constantly changing data.

Expensive Dynamic Rendering

Page performance suffers.

No Attribute Migration

Existing posts become invalid.

Global CSS

Themes and other plugins break.

Unsecured API Calls

Private data becomes exposed.

AI Requests on Every Change

Usage costs and performance increase.

Ignoring Accessibility

The block becomes difficult to use.

Best Practices for Gutenberg Block Development

A professional block should:

Use a unique block namespace.

Define metadata with block.json.

Keep attributes minimal.

Use static blocks for primarily static content.

Use dynamic blocks for data that changes independently.

Use WordPress-provided editor components where practical.

Reuse standard blocks through inner blocks where appropriate.

Validate dynamic data.

Protect API endpoints.

Keep external API credentials server-side.

Cache expensive dynamic data.

Make all UI strings translation-ready.

Support accessibility.

Use scoped CSS.

Test existing block content after updates.

Maintain attribute migrations and deprecations.

Test production builds.

Professional Gutenberg Plugin Architecture

A scalable block plugin can use:

kdr-blocks/ ├── kdr-blocks.php ├── src/ │   ├── blocks/ │   │   ├── product-card/ │   │   │   ├── block.json │   │   │   ├── edit.js │   │   │   ├── save.js │   │   │   └── style.css │   │   ├── pricing-table/ │   │   └── ai-assistant/ │   │ │   ├── components/ │   ├── services/ │   ├── api/ │   └── database/ │ ├── build/ ├── languages/ └── tests/

Each block can remain focused while shared services handle common functionality.

Gutenberg Block Release Checklist

Before publishing a custom block:

☑ Unique block name ☑ block.json verified ☑ Editor tested ☑ Frontend tested ☑ Static/dynamic decision verified ☑ Attributes documented ☑ Attribute migration tested ☑ API permissions tested ☑ Dynamic data validated ☑ Output escaped ☑ CSS scoped ☑ Accessibility checked ☑ JavaScript localized ☑ Responsive layout tested ☑ Theme compatibility tested ☑ Performance tested ☑ Existing posts tested ☑ Production build tested ☑ AI usage controls tested where applicable ☑ WooCommerce compatibility tested where applicable

Conclusion

Gutenberg blocks provide a powerful way for WordPress plugins to create modern, visual, and reusable experiences inside the Block Editor.

The basic concept is simple:

Block Metadata

Editor Interface

Attributes

Save / Render

But professional block development requires more:

Security

Performance

Accessibility

Internationalization

Compatibility

Migration

Testing

For ThemeKaddora, Gutenberg can become an important product layer across:

WooCommerce

AI

Analytics

SaaS

Marketing

Business tools

Content components

Instead of creating isolated blocks without a common strategy, ThemeKaddora can build a reusable block system with shared components, API services, styling conventions, accessibility patterns, and testing standards.

The strongest custom blocks don't simply add more options to the editor.

They make difficult functionality feel simple.

A good block answers three questions quickly:

What can I configure?

What will this look like?

What will happen when I publish it?

When block development is designed around those questions, plugins can deliver powerful functionality without making WordPress editing unnecessarily complicated.

The goal is not merely to create a custom Gutenberg block.

The goal is to create a reliable, accessible, performant, and intuitive building component that fits naturally into the WordPress editor.

Frequently Asked Questions

What is Gutenberg?

Gutenberg is the project and technology behind the WordPress Block Editor, which allows content to be composed from individual blocks.

Can WordPress plugins create custom Gutenberg blocks?

Yes. Plugins can register custom blocks that provide their own editor controls, frontend rendering, and functionality.

What is block.json?

block.json is a metadata file that describes a WordPress block, including its name, title, scripts, styles, attributes, supports, and other configuration.

Should I build a static or dynamic block?

Use a static block when the content is primarily stored in the post. Use a dynamic block when the output depends on information that can change independently, such as products, analytics, or live external data.

Can Gutenberg blocks use React?

Yes. The WordPress Block Editor uses React-based technology, and custom blocks can use WordPress-provided React components and packages.

Can Gutenberg blocks use REST APIs?

Yes. Blocks can use REST APIs to retrieve dynamic information such as products, analytics, settings, or other plugin data.

How do I secure a custom block?

Secure any API or dynamic functionality using authentication, authorization, capability checks, validation, object ownership controls, safe database queries, and escaped output.

Should block attributes store complete database objects?

Usually not. Store the minimum configuration required, such as an object ID, and retrieve current data when necessary.

Can Gutenberg blocks work with WooCommerce?

Yes. WooCommerce-related plugins can create blocks for products, reports, recommendations, comparisons, and other store functionality.

Can Gutenberg blocks use AI?

Yes. AI-powered blocks can generate content, summaries, recommendations, FAQs, and other outputs. AI credentials should remain server-side and requests should be protected by permissions and usage limits.

Why choose Themekaddora?

Themekaddora provides lightweight, responsive, SEO-friendly WordPress themes with fast performance, WooCommerce compatibility, flexible customization, accessibility-conscious design, modern templates, regular updates, and professional support—providing a strong foundation for businesses building digital products and product-focused websites.

Comments (0)
Login or create account to leave comments

We use cookies to personalize your experience. By continuing to visit this website you agree to our use of cookies

More