Skip to main content
When updating block markup and attributes, you need to provide a migration path for existing content. Block deprecation allows the editor to recognize and upgrade old block versions.

Overview

For more details, see the block deprecation tutorial on the WordPress Developer Blog. When updating blocks, you can:
  1. Create a new block with a different name (no deprecation needed)
  2. Provide deprecated versions to upgrade existing content

How deprecations work

Deprecations are not a chain of sequential updates. Instead:
  1. If the current save doesn’t match, the first deprecation is tried
  2. If that deprecation’s save produces valid content, it’s used to parse attributes
  3. If it has a migrate function, that runs with the parsed attributes
  4. If the first deprecation fails, subsequent deprecations are tried
  5. Once a valid deprecation is found, attributes pass to the current save
  6. The block is now valid and the process stops
If a deprecation’s save doesn’t produce valid content, it’s skipped entirely—even if isEligible would return true and even if it has a migrate function.

Deprecation structure

Deprecations are defined in the deprecated array:
Each deprecation object includes:
object
required
The attribute definition from the deprecated version
object
The supports definition from the deprecated version
function
required
The save function from the deprecated version
function
Function to transform old attributes to new formatParameters:
  • attributes (object) - Old attributes
  • innerBlocks (array) - Old inner blocks
Returns:
  • object | [object, array] - New attributes or [attributes, innerBlocks]
function
Determines if a technically valid block should still be migratedParameters:
  • attributes (object) - Raw block attributes
  • innerBlocks (array) - Current inner blocks
  • data (object) - Contains blockNode and block
Returns:
  • boolean - Whether to run this deprecation
attributes, supports, and save are not inherited from the current version. You must define them in each deprecation.

Basic example: Changing markup

Changing from <p> to <div>:

Renaming attributes

Use the migrate function to transform attributes:

Migrating to inner blocks

Move attribute content to inner blocks:

Using isEligible

Migrate technically valid blocks that still need updates:

Best practices

Version organization

Store each deprecation as a named constant:

Maintain fixtures

Keep test fixtures for each version:

Avoid function imports

Imported functions can change and break deprecations:

Update multiple deprecations

If adding a migration (e.g., moving to InnerBlocks), update the migrate function in all affected deprecations:

Common scenarios

Changing attribute source

Adding new attributes

Changing supports

Testing deprecations

Always test that:
  1. Old content migrates successfully
  2. Multiple deprecation versions work
  3. The migrate function handles edge cases
For real-world examples, see the core block library which contains numerous deprecation examples.