Block variations are one of the most powerful ways to extend WordPress and curate the editing experience for your users. In this article, you will learn how to effectively create block variations and discover ways to incorporate them into your workflows. Let’s get started.
Table of Contents
The Block Variations API
The Block Variations API allows you to create additional versions of existing blocks that differ by a set of initial attributes or inner blocks.
A variation is defined by an object that contains a set of properties. I will cover many of the most important properties in this article, and you can review the rest in the Block Variations API documentation.
- name (type string) – A unique and machine-readable name.
- title (optional, type string) – A human-readable variation title.
- icon (optional, type string | Object) – An icon for the variation in the Editor UI.
- attributes (optional, type Object) – Values that override the original block’s default attributes.
- innerBlocks (optional, type Array[]) – The initial configuration of nested blocks.
- isDefault (optional, type boolean) – Defaults to false. Indicates whether the current variation is the default one.
- isActive (optional, type Function | string[]) – A function or an array of block attributes that are used to determine if the variation is active when the block is selected. The function accepts
blockAttributes
andvariationAttributes
.
Once defined, variations can be created using the function registerBlockVariation()
or unregistered using unregisterBlockVariation()
. The examples below demonstrate how to use both.
Variations can also be declared during the registration of a block. Refer to the Block Registration API for more details. This approach is useful if you are building a custom block and want to provide additional variations.
Getting set up
Block variations are registered in JavaScript, so you first need to create a JavaScript file.
I am going to assume you want to add block variations to a theme, but this approach can be easily adapted to a plugin. The only real difference is where the files and functions are located. For now, let’s create variations.js
and put the file in our theme’s assets/js
folder.
Next, you need to enqueue variations.js
using the enqueue_block_editor_assets
hook and the standard wp_equeue_script()
function. This code should generally be placed in your theme’s functions.php
file unless you have a more advanced setup.
function example_enqueue_block_variations() {
wp_enqueue_script(
'example-enqueue-block-variations',
get_template_directory_uri() . '/assets/js/variations.js',
array( 'wp-blocks', 'wp-dom-ready' ),
wp_get_theme()->get( 'Version' ),
false
);
}
add_action( 'enqueue_block_editor_assets', 'example_enqueue_block_variations' );
Note that wp-blocks
and wp-dom-ready
are listed as dependencies. These will be used to register and unregister the block variations in the following steps, but the setup is complete for now.
The WordPress Developer Blog typically uses ESNext syntax for JavaScript examples. However, since it’s common to add block variations to themes that do not include a build process, the examples here will use plain JavaScript. If your project already has a build process, feel free to use ESNext instead. A great resource for this approach can be found in Beyond block styles, part 1: using the WordPress scripts package with themes.
Creating a block variation
With the variation.js
file enqueued, you can now register block variations using the registerBlockVariation()
function. This function comes from the wp-blocks
dependency that I added to the enqueue function earlier and can be called by prefixing the function with wp.block.
, or like this:
const { registerBlockVariation } = wp.blocks;
registerBlockVariation( ... );
Use whichever method you prefer—I will use wp.blocks.registerBlockVariation()
throughout this article.
The registerBlockVariation()
function accepts the name of the original block and an object that defines the variation you want to create. Let’s look at an example.
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'media-text-custom',
title: 'Media & Text Custom',
attributes: {
align: 'wide',
backgroundColor: 'tertiary'
},
}
);
The code above registers a block variation for the Media & Text block (core/media-text
). I have given it a unique name
and a title
, and have set a few attribute values. When this variation is inserted into the Editor, it will be a Media & Text block aligned wide, with a background color set to tertiary
.
You can technically create a block variation without a unique name, although I recommend against this practice. A unique name
allows the Editor to differentiate between your variation and others that may exist.
The variation will appear like this when using the Twenty Twenty-Three theme:

You may have noticed that both the Media & Text block and the “Media & Text Custom” variation appear in the Inserter. This is the right outcome, but you can add the property isDefault: true
to replace the original block with your variation. This method comes in handy when you want to modify the initial state of Core blocks, or third-party blocks.
Let’s update the example so that the variation becomes the default. With this change, Media & Text blocks are always aligned wide and have a background color when inserted.
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'media-text-default',
title: 'Media & Text',
attributes: {
align: 'wide',
backgroundColor: 'tertiary'
},
isDefault: true
}
);
Since the variation is now the default, I have changed the title back to “Media & Text” and the Inserter will now only display a single Media & Text block. From a user perspective, they are just using the default block.