Why blocks changed everything in WordPress
WordPress served the web through a single rich-text box for over fifteen years. That changed in December 2018 when version 5.0 shipped with the Gutenberg block editor. Instead of pasting raw HTML or wrestling with shortcodes, every piece of content became a discrete block: a paragraph, an image, a gallery, a button, a table. Blocks can be moved, duplicated, grouped, and styled independently.
In 2026 the block editor is no longer optional. It powers post editing, page building, and, with full site editing, the entire theme layer. Whether you are a site owner publishing articles or a developer shipping client projects, understanding blocks, patterns, and the Site Editor is a core skill.
This guide walks through every layer of the block ecosystem, from the inserter panel to building a custom block theme from scratch.
Understanding the block inserter
The block inserter is the gateway to every element you can place on a page. Open it by clicking the blue + button in the top-left toolbar or by typing / inside an empty paragraph.
The inserter groups blocks into categories:
- Text - paragraph, heading, list, quote, code, preformatted, pullquote, verse
- Media - image, gallery, audio, video, cover, file
- Design - buttons, columns, group, row, stack, separator, spacer
- Widgets - shortcode, archives, categories, latest posts, search, social icons
- Theme - navigation, site logo, site title, query loop, template part, post title, post content
- Embeds - YouTube, Twitter, Spotify, Vimeo, and dozens more via oEmbed
Each block exposes its own toolbar (inline formatting, alignment, link) and a sidebar panel with advanced settings (HTML anchor, additional CSS classes, color, typography). Mastering the inserter means you rarely need a page builder plugin for standard layouts.
Keyboard shortcuts that save time
Productive block editing relies on shortcuts:
/followed by a block name inserts it instantlyCtrl+Shift+D(Cmd on macOS) duplicates the selected blockCtrl+Alt+Tinserts a block before the current oneCtrl+Alt+Yinserts a block after the current oneShift+Alt+Zremoves the selected blockCtrl+Shift+Kremoves a link from selected text
Combine these with the drag handle on each block, and you can rearrange complex layouts without touching a mouse.
Creating and managing synced patterns (reusable blocks)
WordPress 6.3 renamed “reusable blocks” to “synced patterns,” but the concept remains the same: save a block or group of blocks once and insert it anywhere across your site. When you edit one instance, every placement updates.
How to create a synced pattern
- Select one or more blocks in the editor.
- Open the block toolbar and click the three-dot menu.
- Choose Create pattern.
- Give the pattern a name and a category.
- Toggle Synced on. (Leaving it off creates a standard, non-synced pattern.)
- Click Create.
The pattern now appears in the inserter under the Patterns tab and inside Synced category.
Practical use cases
- Call-to-action banners - a single CTA block group used on every landing page, updated once when the campaign changes.
- Testimonial sections - a columns block with client quotes that stays consistent across service pages.
- Disclaimer notices - legal text that must remain identical site-wide.
- Newsletter signup forms - a form block synced across the blog sidebar and footer.
Managing patterns from the admin
Navigate to Appearance > Editor > Patterns (or the standalone Patterns screen at /wp-admin/edit.php?post_type=wp_block) to view, edit, duplicate, export, or delete your patterns. You can also convert a synced pattern into a regular (non-synced) pattern by opening it and toggling the sync status off.
Block patterns and the pattern directory
While synced patterns are your own reusable components, block patterns are pre-designed layouts you insert and customize freely. WordPress ships with built-in patterns (hero sections, testimonial grids, pricing tables, feature lists), and thousands more are available in the official pattern directory at wordpress.org/patterns.
Using patterns from the directory
- Open the inserter and click the Patterns tab.
- Browse categories or search by keyword.
- Click a pattern to insert it into the editor.
- Modify text, images, colors, and spacing to match your brand.
Because patterns become independent copies after insertion, you can change every detail without affecting the original.
Registering a custom block pattern in PHP
Themes and plugins can register patterns programmatically. Here is a minimal example in functions.php:
<?php
declare(strict_types=1);
add_action('init', function (): void {
register_block_pattern(
'wppoland/hero-with-cta',
[
'title' => __('Hero with CTA', 'wppoland'),
'description' => __('A full-width hero section with heading, paragraph, and button.', 'wppoland'),
'categories' => ['featured', 'banner'],
'keywords' => ['hero', 'cta', 'banner'],
'content' => '
<!-- wp:cover {"overlayColor":"contrast","isUserOverlayColor":true,"minHeight":500,"align":"full"} -->
<div class="wp-block-cover alignfull" style="min-height:500px">
<span class="wp-block-cover__background has-contrast-background-color"></span>
<div class="wp-block-cover__inner-container">
<!-- wp:heading {"textAlign":"center","level":1} -->
<h1 class="wp-block-heading has-text-align-center">Your headline here</h1>
<!-- /wp:heading -->
<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">Supporting text that explains the value proposition.</p>
<!-- /wp:paragraph -->
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
<div class="wp-block-buttons">
<!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">Get started</a></div>
<!-- /wp:button -->
</div>
<!-- /wp:buttons -->
</div>
</div>
<!-- /wp:cover -->
',
]
);
});
From WordPress 6.0 onward you can also place pattern files in a patterns/ directory at the theme root. Each file uses a header comment for metadata and returns block markup, enabling auto-registration without register_block_pattern().
Full site editing: how the Site Editor replaces the Customizer
Full site editing (FSE) is the umbrella term for using blocks to control every part of your site, not just post content but also headers, footers, sidebars, archive layouts, and 404 pages. It shipped incrementally across WordPress 5.9 through 6.5 and is now the standard approach for block themes.
What full site editing replaces
| Classic workflow | FSE equivalent |
|---|---|
| Customizer panels | Global Styles sidebar in the Site Editor |
| Widget areas | Template parts (header, footer, sidebar) |
| PHP template files | HTML block-markup templates |
add_theme_support() calls | theme.json settings |
| Menu management screen | Navigation block |
Accessing the Site Editor
With a block theme active, go to Appearance > Editor. The interface opens in a visual preview. From the left sidebar you can navigate to:
- Templates - index, single, page, archive, 404, search, home, and any custom templates
- Template parts - header, footer, sidebar, and custom parts
- Patterns - all registered and user-created patterns
- Styles - global typography, colors, spacing, and per-block style overrides
- Navigation - menu management powered by the Navigation block
Every change is live-previewed and saved to the database. For theme developers, changes can be exported as theme files for version control.
Creating custom templates and template parts
Templates define the structure of a page type. Template parts are reusable fragments (header, footer) shared across templates.
Creating a template in the Site Editor
- Open Appearance > Editor > Templates.
- Click Add New Template.
- Select a template type (page, single post, category, author, custom).
- Build the layout using blocks: add a header template part at the top, a query loop for posts, a footer template part at the bottom.
- Save.
Template markup format
Under the hood, every template is a block-markup HTML file. Here is a simplified templates/single.html:
<!-- wp:template-part {"slug":"header","area":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
<!-- wp:post-title {"level":1} /-->
<!-- wp:post-featured-image /-->
<!-- wp:post-content /-->
<!-- wp:post-terms {"term":"category"} /-->
<!-- wp:post-terms {"term":"post_tag"} /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","area":"footer"} /-->
Template parts live in the parts/ directory. A parts/header.html might look like:
<!-- wp:group {"tagName":"header","layout":{"type":"flex","justifyContent":"space-between"}} -->
<header class="wp-block-group">
<!-- wp:site-title /-->
<!-- wp:navigation /-->
</header>
<!-- /wp:group -->
This structure eliminates PHP template tags (get_header(), the_title(), the_content()) in favor of declarative block markup. The result is a theme that designers and content editors can modify directly in the Site Editor.
theme.json configuration basics
theme.json is the single configuration file that controls what the editor exposes and how the front end looks. It sits at the root of your block theme.
Minimal theme.json example
{
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "primary", "color": "#1e40af", "name": "Primary" },
{ "slug": "secondary", "color": "#9333ea", "name": "Secondary" },
{ "slug": "base", "color": "#ffffff", "name": "Base" },
{ "slug": "contrast", "color": "#1a1a1a", "name": "Contrast" }
],
"gradients": [],
"defaultPalette": false,
"defaultGradients": false
},
"typography": {
"fontFamilies": [
{
"fontFamily": "Inter, sans-serif",
"slug": "body",
"name": "Body"
},
{
"fontFamily": "'Space Grotesk', sans-serif",
"slug": "heading",
"name": "Heading"
}
],
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Small" },
{ "slug": "medium", "size": "1rem", "name": "Medium" },
{ "slug": "large", "size": "1.5rem", "name": "Large" },
{ "slug": "x-large", "size": "2.25rem", "name": "Extra Large" }
]
},
"spacing": {
"units": ["rem", "vh", "vw", "%"],
"spacingSizes": [
{ "slug": "10", "size": "0.5rem", "name": "Tiny" },
{ "slug": "20", "size": "1rem", "name": "Small" },
{ "slug": "30", "size": "1.5rem", "name": "Medium" },
{ "slug": "40", "size": "2.5rem", "name": "Large" },
{ "slug": "50", "size": "4rem", "name": "Extra Large" }
]
},
"layout": {
"contentSize": "720px",
"wideSize": "1200px"
},
"appearanceTools": true
},
"styles": {
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
},
"typography": {
"fontFamily": "var(--wp--preset--font-family--body)",
"fontSize": "var(--wp--preset--font-size--medium)",
"lineHeight": "1.6"
},
"elements": {
"heading": {
"typography": {
"fontFamily": "var(--wp--preset--font-family--heading)",
"fontWeight": "700"
}
},
"link": {
"color": {
"text": "var(--wp--preset--color--primary)"
}
}
},
"blocks": {
"core/button": {
"color": {
"background": "var(--wp--preset--color--primary)",
"text": "var(--wp--preset--color--base)"
},
"border": {
"radius": "4px"
}
}
}
}
}
Key sections explained
- version - always use
3for WordPress 6.6 and later. - settings - defines what controls appear in the editor: color palettes, font families, font sizes, spacing presets, layout widths, and feature toggles.
- styles - applies default CSS values to the root, elements (headings, links, buttons, captions), and individual blocks.
- appearanceTools - a shorthand that enables border, spacing, typography, and dimension controls in the sidebar.
The engine converts theme.json into CSS custom properties (like --wp--preset--color--primary) that cascade through the entire site. This means one file governs the design tokens for both the editor and the front end.
Best block plugins for WordPress in 2026
The core editor covers most needs, but third-party block plugins fill the gaps with advanced layouts, design controls, and specialized blocks.
Spectra (formerly Ultimate Addons for Gutenberg)
Developed by Brainstorm Force (the team behind the Starter Templates plugin), Spectra adds over 30 blocks: countdown timers, star ratings, icon lists, price lists, modals, tabs, and a full-featured forms block. It includes a container block with flex and grid layout modes, making it suitable for complex page designs without a traditional page builder. Pricing varies depending on feature tier.
GenerateBlocks
Built by the GeneratePress team, GenerateBlocks takes a minimal approach: four core blocks (container, headline, buttons, image) that rely on flexible settings rather than dozens of single-purpose blocks. The result is lightweight output with minimal CSS. Power users appreciate the query loop integration and the dynamic data system that pulls post meta, custom fields, and taxonomy data into block layouts.
Stackable
Stackable offers 40+ blocks with a visual design library of over 200 pre-built layouts. Its standout feature is a unified design system where global typography, color palettes, and spacing scales propagate to every Stackable block automatically. The free version covers most use cases, while the premium tier adds dynamic content, conditional display, and motion effects.
Kadence Blocks
Kadence Blocks provides a row/column layout system, advanced heading block, info boxes, icon lists, table of contents, and a form block. The design library includes full-page and section patterns. Kadence pairs especially well with the Kadence theme, sharing a design token system. Pricing for the pro tier is individual and varies based on site count.
Choosing the right plugin
| Criterion | Spectra | GenerateBlocks | Stackable | Kadence Blocks |
|---|---|---|---|---|
| Total blocks | 30+ | 4 (flexible) | 40+ | 20+ |
| Design approach | Feature-rich | Minimalist | Library-driven | Balanced |
| Performance overhead | Medium | Low | Medium | Low-Medium |
| Free version strength | Strong | Strong | Strong | Strong |
| Best paired with | Starter Templates | GeneratePress | Any theme | Kadence Theme |
Pick GenerateBlocks for performance-critical projects, Spectra or Stackable for design-heavy pages, and Kadence Blocks when you need a strong form builder alongside layout tools.
Building a simple block theme from scratch
Combining everything above, here is a step-by-step walkthrough for creating a minimal block theme.
Step 1: folder structure
my-block-theme/
style.css
theme.json
functions.php
templates/
index.html
single.html
page.html
404.html
parts/
header.html
footer.html
patterns/
hero-banner.php
Step 2: style.css header
/*
Theme Name: My Block Theme
Theme URI: https://wppoland.com
Author: wppoland.com
Author URI: https://wppoland.com
Description: A minimal block theme for learning full site editing.
Version: 1.0.0
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: my-block-theme
*/
No additional CSS is needed here. All styling flows through theme.json and the global styles system.
Step 3: theme.json
Use the example from the earlier section. Adjust the color palette and typography to match your brand.
Step 4: templates
templates/index.html (the fallback template):
<!-- wp:template-part {"slug":"header","area":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
<!-- wp:query {"queryId":1,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","inherit":true}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-excerpt /-->
<!-- wp:post-date /-->
<!-- /wp:post-template -->
<!-- wp:query-pagination -->
<!-- wp:query-pagination-previous /-->
<!-- wp:query-pagination-numbers /-->
<!-- wp:query-pagination-next /-->
<!-- /wp:query-pagination -->
</div>
<!-- /wp:query -->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","area":"footer"} /-->
templates/404.html:
<!-- wp:template-part {"slug":"header","area":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Page not found</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>The page you are looking for does not exist. Try searching or return to the homepage.</p>
<!-- /wp:paragraph -->
<!-- wp:search {"label":"Search","buttonText":"Search"} /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","area":"footer"} /-->
Step 5: template parts
parts/header.html:
<!-- wp:group {"tagName":"header","style":{"spacing":{"padding":{"top":"var:preset|spacing|20","bottom":"var:preset|spacing|20"}}},"layout":{"type":"constrained"}} -->
<header class="wp-block-group" style="padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)">
<!-- wp:group {"layout":{"type":"flex","justifyContent":"space-between"}} -->
<div class="wp-block-group">
<!-- wp:site-title /-->
<!-- wp:navigation {"layout":{"type":"flex"}} /-->
</div>
<!-- /wp:group -->
</header>
<!-- /wp:group -->
parts/footer.html:
<!-- wp:group {"tagName":"footer","style":{"spacing":{"padding":{"top":"var:preset|spacing|30","bottom":"var:preset|spacing|30"}}},"backgroundColor":"contrast","textColor":"base","layout":{"type":"constrained"}} -->
<footer class="wp-block-group has-base-color has-contrast-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)">
<!-- wp:paragraph {"align":"center","fontSize":"small"} -->
<p class="has-text-align-center has-small-font-size">Built with WordPress and blocks.</p>
<!-- /wp:paragraph -->
</footer>
<!-- /wp:group -->
Step 6: auto-registered pattern
patterns/hero-banner.php:
<?php
/**
* Title: Hero banner
* Slug: my-block-theme/hero-banner
* Categories: featured, banner
* Keywords: hero, cta, landing
*/
?>
<!-- wp:cover {"overlayColor":"primary","isUserOverlayColor":true,"minHeight":480,"align":"full"} -->
<div class="wp-block-cover alignfull" style="min-height:480px">
<span class="wp-block-cover__background has-primary-background-color"></span>
<div class="wp-block-cover__inner-container">
<!-- wp:heading {"textAlign":"center","level":1,"textColor":"base"} -->
<h1 class="wp-block-heading has-text-align-center has-base-color has-text-color">Welcome to My Block Theme</h1>
<!-- /wp:heading -->
<!-- wp:paragraph {"align":"center","textColor":"base"} -->
<p class="has-text-align-center has-base-color has-text-color">A lightweight, block-first WordPress theme.</p>
<!-- /wp:paragraph -->
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
<div class="wp-block-buttons">
<!-- wp:button {"backgroundColor":"base","textColor":"primary"} -->
<div class="wp-block-button"><a class="wp-block-button__link has-primary-color has-base-background-color has-text-color has-background wp-element-button">Learn more</a></div>
<!-- /wp:button -->
</div>
<!-- /wp:buttons -->
</div>
</div>
<!-- /wp:cover -->
Step 7: functions.php (optional enhancements)
<?php
declare(strict_types=1);
add_action('after_setup_theme', function (): void {
add_theme_support('wp-block-styles');
add_theme_support('editor-styles');
add_editor_style('style.css');
});
add_action('wp_enqueue_scripts', function (): void {
wp_enqueue_style(
'my-block-theme-style',
get_stylesheet_uri(),
[],
wp_get_theme()->get('Version')
);
});
Upload the folder to wp-content/themes/, activate it, and open Appearance > Editor. You now have a fully functional block theme where every template, pattern, and style is editable from the browser.
Advanced tips for block-first development
Lock blocks to prevent accidental edits
When building templates for clients, lock blocks to restrict movement and removal:
<!-- wp:group {"lock":{"move":true,"remove":true}} -->
<div class="wp-block-group">
<!-- wp:paragraph -->
<p>This block cannot be moved or deleted by editors.</p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:group -->
Content inside locked blocks remains editable, but the structural integrity stays intact.
Use block variations for consistency
Register block variations to provide pre-configured instances of core blocks. For example, a “team member” variation of the media-and-text block:
<?php
add_action('enqueue_block_editor_assets', function (): void {
wp_add_inline_script(
'wp-blocks',
"wp.blocks.registerBlockVariation('core/media-text', {
name: 'team-member',
title: 'Team Member',
attributes: {
mediaPosition: 'left',
verticalAlignment: 'center',
},
scope: ['inserter'],
});"
);
});
Variations appear as distinct blocks in the inserter while sharing the parent block’s code.
Leverage the create-block package
For custom blocks beyond what patterns and variations cover, use the official @wordpress/create-block scaffolding tool:
npx @wordpress/create-block my-custom-block --variant dynamic
This generates a plugin with build tooling (webpack, Babel, ESLint), a React-based edit function, and a PHP render_callback for dynamic server-side rendering. It is the recommended path for any block that needs to fetch data, run queries, or display dynamic content.
Common mistakes and how to avoid them
Mixing classic and block templates. A theme is either a block theme or a classic theme. Placing index.php alongside templates/index.html creates unpredictable fallback behavior. Commit to one approach per theme.
Overriding theme.json with inline CSS. Inline styles bypass the global styles cascade and break the Site Editor’s style controls. Always use theme.json presets and CSS custom properties instead.
Ignoring the patterns directory. Many developers still register patterns exclusively through PHP. The patterns/ directory with file headers is simpler, requires no hook registration, and keeps pattern markup separate from logic.
Forgetting to test with different user roles. Editors and Authors see a filtered version of the block editor. Template editing, global styles, and certain blocks may be hidden based on capabilities. Always verify the editing experience for every role that will use it.
Not exporting Site Editor changes. Modifications made in the browser are stored in the database. If you redeploy the theme without exporting those changes to files, they vanish. Use the Site Editor’s export feature or the wp theme export WP-CLI command to sync changes back to version control.
The future of blocks in WordPress
The Gutenberg project is organized into four phases: easier editing (shipped), customization (current, FSE), collaboration (in progress), and multilingual (planned). Phase 3, real-time collaboration, will bring Google Docs-style simultaneous editing to the block editor. Phase 4 aims to make WordPress natively multilingual without plugins.
Block themes are already the default for new WordPress installations. Classic themes remain supported, but new API development and design tooling focuses on the block paradigm. Investing in block-first skills now positions your team for every major WordPress release through 2028 and beyond.
How wppoland.com approaches block development
At wppoland.com, we build every client project on block-first architecture. Our workflow starts with theme.json design tokens, moves into custom block patterns for repeating sections, and finishes with locked templates that give content editors freedom without structural risk.
For projects that need blocks beyond what the core and existing plugins offer, we develop custom blocks using the @wordpress/create-block toolchain, with server-side rendering for dynamic content and full integration with the Site Editor’s global styles.
If you need a custom block theme, a migration from a classic theme to full site editing, or bespoke block development for your content workflow, reach out to the wppoland.com team. We deliver block solutions tailored to your editorial and business requirements, with pricing structured individually based on project scope.

