How to register block patterns and variations via JS in WordPress

Contents

Introduction

This tutorial explains, in depth, how to register Block Patterns and Block Variations in WordPress using JavaScript. It covers APIs, recommended workflow, enqueuing, example code (ready to paste), registration and unregistration, internationalization, pattern categories, variations with inner blocks, and common pitfalls.

Prerequisites

  • WordPress 5.5 for block patterns support use the latest WordPress for the most complete API.
  • Basic knowledge of Gutenberg blocks and ESNext/webpack or the WordPress script loader.
  • A plugin or theme able to enqueue editor scripts (enqueue_block_editor_assets or block editor build).
  • Familiarity with block HTML comments, e.g. … .

APIs and Concepts Overview

Two distinct but related features are covered:

  • Block Patterns — Reusable content templates (groups of blocks) that users can insert from the inserters Patterns panel.
  • Block Variations — Alternate presets/configurations of a specific block type that appear as variation choices when inserting or transforming a block (for example, multiple preset layouts for core/columns, different button styles for core/button).

Key JavaScript functions (available via wp. packages or @wordpress/blocks) include:

  • registerBlockPattern( name, settings )
  • unregisterBlockPattern( name )
  • registerBlockPatternCategory( name, settings )
  • registerBlockVariation( blockName, variation )
  • unregisterBlockVariation( blockName, variationName )

How to Add the Script to the Editor

Enqueue a script that runs in the block editor. Below is a minimal PHP example for a plugin that enqueues a built JS file for the editor.


If using @wordpress/scripts and ESNext, the built/registrations.js will be created by the bundler and will export/register code at runtime in the editor.

Registering Block Patterns (JS)

Block patterns are content strings composed of block HTML markup (the same markup the editor uses when storing content). Use registerBlockPattern to add a pattern that appears in the Patterns tab of the inserter.

Minimum pattern settings

  • title (string) — human-readable title
  • content (string) — block HTML string with block comments
  • categories (array of slugs) — optional categories help organize patterns
  • keywords (array) — optional search keywords
  • viewportWidth — optional visual width for previews

Example: Register a Hero Pattern

const { registerBlockPattern } = wp.blocks
const { __ } = wp.i18n

registerBlockPattern( my-plugin/hero-section, {
  title: __( Hero: Centered heading and CTA, my-plugin ),
  description: __( Large heading, short paragraph and CTA centered on the page., my-plugin ),
  categories: [ featured, text ],
  keywords: [ hero, cta, heading ],
  viewportWidth: 1200,
  content: 
    
    

Your headline here

A short subheading that supports the headline.

, } )

Registering Pattern Categories (Optional)

Pattern categories help organize patterns in the Patterns panel. Register categories before registering patterns that use them.

const { registerBlockPatternCategory } = wp.blocks

registerBlockPatternCategory( my-plugin, { label: My Plugin Patterns } )

Unregister a Core Pattern (Optional)

To hide or remove an existing pattern (for example a core pattern), use unregisterBlockPattern.

const { unregisterBlockPattern } = wp.blocks

unregisterBlockPattern( core/three-columns )

Registering Block Variations (JS)

Block variations are alternate presets for a specific block type. Use registerBlockVariation( blockName, variationObject ). Variations can set attributes, provide initial inner blocks, supply an icon and description, and set a name (unique per block).

Variation object keys commonly used

  • name — unique variation slug for this block (do not include the block namespace)
  • title — human label
  • description — optional
  • icon — optional dashicon or element
  • attributes — attribute values to apply when variation is chosen
  • innerBlocks — array of inner block tuples to create a default inner block structure
  • isDefault — boolean whether this becomes the default variant for new insertions
  • isActive — optional function(attributes) returning true if block should render as this variation (used for transforms/active state)

Example 1: Simple button variation

const { registerBlockVariation } = wp.blocks
const { __ } = wp.i18n

registerBlockVariation( core/button, {
  name: ghost,
  title: __( Ghost Button, my-plugin ),
  description: __( Transparent background with an outline look., my-plugin ),
  icon: admin-links,
  attributes: {
    className: is-style-ghost
  },
  isDefault: false
} )

Example 2: Columns with innerBlocks preset

For blocks that accept inner blocks (columns, group, navigation), variations can specify innerBlocks to create a ready-to-edit structure on insert.

registerBlockVariation( core/columns, {
  name: two-thirds-one-third,
  title: Two thirds / one third,
  attributes: {},
  innerBlocks: [
    [ core/column, { width: 66 } ],
    [ core/column, { width: 33 } ]
  ],
  isDefault: false
} )

Example 3: Active-detection logic via isActive

isActive can be helpful when rendering a block with attributes that match a named variation — useful during conversion or when determining which variation is selected.

registerBlockVariation( core/group, {
  name: promo-dark,
  title: Promo (Dark),
  attributes: { className: promo promo--dark },
  isActive: ( attributes ) => {
    return attributes  typeof attributes.className === string  attributes.className.indexOf( promo--dark ) !== -1
  },
} )

Unregister a Variation

const { unregisterBlockVariation } = wp.blocks

// Remove outline variation from core/button
unregisterBlockVariation( core/button, outline )

Alternative: Declaring Variations in block.json

When creating a custom block that ships with block.json metadata, variations can be declared directly inside block.json using the variations key. These will be automatically registered when register_block_type_from_metadata is used or when the block is registered by core tooling. Use JS registration for dynamic, runtime or third-party modifications.

{
  apiVersion: 2,
  name: my-plugin/my-block,
  title: My Block,
  variations: [
    {
      name: compact,
      title: Compact,
      attributes: {
        size: compact
      }
    }
  ]
}

Practical Packaging / Build Tips

  1. Use @wordpress/scripts or your bundler to produce a build file that is enqueued in the editor using enqueue_block_editor_assets.
  2. Ensure correct dependencies in wp_enqueue_script — include wp-blocks and wp-i18n at minimum if using the global wp. packages. If bundling with packages, import from @wordpress/blocks and @wordpress/i18n instead.
  3. For translations, use the __() or _x() functions from wp.i18n when registering patterns/variations. Make sure to generate POT files and load the textdomain if needed.

Examples Using ES Modules (Recommended When Bundling)

import { registerBlockPattern, registerBlockVariation } from @wordpress/blocks
import { __ } from @wordpress/i18n

registerBlockPattern( my-plugin/hero, {
  title: __( Hero, my-plugin ),
  content: 
    
    

Ready to start?

Short promo text here.

, } ) registerBlockVariation( core/button, { name: ghost, title: __( Ghost, my-plugin ), attributes: { className: is-style-ghost } } )

Common Pitfalls and Troubleshooting

  • Pattern content invalid HTML: Ensure the pattern content uses correct block comment markup ( … ). Incorrect markup prevents parsing and insertion.
  • Wrong dependencies: If using global wp. in an enqueued script, include wp-blocks and wp-i18n in the php enqueue dependencies. If bundling, import from @wordpress/blocks and include the package in the build.
  • Timing: Register patterns/variations early in editor load. Enqueue with enqueue_block_editor_assets or register in plugin init that will load the script for the editor.
  • Category missing: If patterns are not visible because the category is not registered, register the pattern category first or use an existing category slug.
  • Cache and editor reload: Clear browser cache or use hard reload when testing changes scripts often cache aggressively during development.
  • Conflicting names: Variation names must be unique per block. Pattern names must follow a namespaced slug format (namespace/name).

Advanced Considerations

  • Dynamically generated patterns or variations: Use JS to compute content or attributes at runtime (for example, injecting dynamic URLs or translations). Keep content safe — do not inject untrusted HTML.
  • Conditionally register/unregister: Use logic to hide core patterns or variations for specific post types by checking wp.data.select(core/editor).getCurrentPostType() at runtime in the editor. Use caution: this couples registrations to editor state and may need dom-ready/event wiring.
  • CSS and styling: Provide editor styles for any classes used in patterns/variations so the preview in the inserter and editor matches the frontend rendering.
  • Remove patterns in themes vs. plugins: Themes commonly register patterns via PHP plugins often register via JS if they need runtime logic. Choose the approach that matches distribution (theme JSON or PHP for themes, plugin PHP or JS for plugins).

Summary of Steps

  1. Decide whether to register patterns/variations via JS or PHP (JS recommended for runtime/dynamic control PHP often used for themes and early registration).
  2. Create and bundle a JS file that imports or uses wp. methods to call registerBlockPattern and registerBlockVariation.
  3. Enqueue the script in the editor using enqueue_block_editor_assets with correct dependencies.
  4. Optionally register pattern categories and add internationalization wrappers for titles/descriptions.
  5. Test by opening the block inserter: Patterns panel for registered patterns and block inserter/toolbar for variations and default choices.

Additional Reference

For further API details and latest additions, reference the official developer documentation (search for registerBlockPattern and registerBlockVariation). Official docs keep API details and examples up to date with WordPress core releases.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Leave a Reply

Your email address will not be published. Required fields are marked *