Building with Synced Patterns and Pattern Overrides

By Ian Svoboda on June 3, 2026

Synced patterns make reusing code across your site a lot easier and since WordPress 7.0 they’ve gotten even more useful. In this post I’ll explain how they work and how to build one.

Last week we looked at contentOnly editing and how WordPress 7.0 turns it on by default for unsynced patterns. That gives editors a guardrail around instance-local edits: they can still tweak the content, but the structure is hidden away unless they explicitly go in to edit it.

That functionality is primarily designed to not overwhelm a user with too many controls. In the end, an unsynced pattern can still be changed in any way you want. These are meant to be almost “copy/pastable” sets of blocks which can be customized independently of each other.

When and why to use synced patterns

Synced patterns solve a different problem: They let you maintain one source of truth for a piece of design and reuse it everywhere. If you’re setting up a group of blocks that should always be the same, no matter where they’re placed, you probably want a synced pattern.

That said, sometimes you find yourself in the classic “Three Bears problem” where you really want a bit of both: blocks that look the same everywhere, but this one piece of text needs to be different. Or perhaps a unique image URL.

This is where pattern overrides come into play. Pattern overrides let specific fields inside that pattern vary per instance. This allows the block’s style, layout, and other settings to remain the same wherever the pattern is used while still letting you customize certain pieces of it.1

The concept of pattern overrides is sort of similar to how a component that accepts props works. You can add props for consumers (i.e. the person/thing using the component) to change things that you want them to change and leave everything else separate.

A synced pattern is a saved block (or group of blocks) where every insertion stays linked to a single source. Edit the source, every instance updates.

Under the hood, synced patterns are stored as wp_block posts. When you insert one into a page or post, WordPress writes a core/block reference with a ref attribute pointing at that post ID. The post you inserted the pattern into stores the reference, and the actual block content lives on the pattern itself.

You’ll find them in the Patterns sidebar under “My patterns,” marked with the synced status indicator. Reach for them when you want something consistent everywhere it appears, like callouts, CTAs, team member cards, or footer blocks. Reach for an unsynced pattern instead when you want a starting layout that each editor can take in their own direction.

Build the pattern

Let’s create the running example. In the editor, build a small Group block containing an Image, a Heading (the name), and a Paragraph (the role). Style it however you’d like. Once you’re happy with how it looks, select the outer Group, click the three-dot Options menu, and choose Create pattern.

In the modal:

  1. Name it Team Member Card.
  2. Pick a Category (or create a new one).
  3. Leave the Synced toggle on.
  4. Save.

The pattern is now a wp_block post and shows up in the Patterns sidebar. Drop it into any post and the markup WordPress saves looks like this:

HTML
<!-- wp:block {"ref":42} /-->

As noted above, the content is referenced by the post ID of the synced pattern.

This is great when you want exactly the same thing everywhere, but most real cards need some per-instance variation (a different person’s name, for example). That’s where overrides come in.

Mark the overridable fields

Open the synced pattern itself by clicking it in the Patterns sidebar and choosing Edit original. You’ll land in an isolated editor scoped to the pattern.

Select the Heading (the name) and open the block inspector. In the Advanced panel, you’ll find an Enable overrides toggle. Turn it on and give the field a meaningful name like member_name. This is the per-attribute identifier that the editor uses to track override values across instances. Repeat for the Paragraph (the role) with the name member_role.

Save the pattern, and the markup core writes for those two blocks looks like this:

HTML
<!-- wp:heading {"metadata":{"name":"member_name","bindings":{"content":{"source":"core/pattern-overrides"}}}} -->
<h2 class="wp-block-heading">Add a name</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"metadata":{"name":"member_role","bindings":{"content":{"source":"core/pattern-overrides"}}}} -->
<p>Add a role</p>
<!-- /wp:paragraph -->

Two moving parts worth pointing out:

  • metadata.name is the unique identifier for that block within the pattern. Overrides need it to track which value belongs to which slot.
  • metadata.bindings ties a specific attribute (here, content) to the core/pattern-overrides source. That source is the binding implementation that knows how to read and write the per-instance value.

Whatever you type in the source pattern becomes the default placeholder. Whatever an editor types on an actual insertion becomes the override stored on that host post.

Use it

Now insert the pattern into a couple of posts. Click the Heading or Paragraph on each insertion and notice what you can (and can’t) do:

  • The name and role are editable text fields.
  • The Image, the wrapping Group, the spacing, the color, the typography settings: all locked. They aren’t bound, so they’re not yours to change from this side.

Type a different name and role for each insertion, save, and look at the rendered output. Same design, different content per card.

This is the same “content editing only” feel from last week’s post on contentOnly, except now the restriction is attribute-level rather than block-level. contentOnly says “you can interact with content-shaped blocks.” Overrides say “you can edit these specific attributes on these specific blocks.” Same philosophy, different scalpel.

The WordPress 7.0 upgrade

Before the 7.0 release, pattern overrides only worked on a hardcoded set of core blocks: Paragraph, Heading, Button, and Image. If you tried to use overrides on a custom block or a third-party block, the “Enable overrides” toggle simply wasn’t there.

In 7.0, that hardcoded list is gone. Any block attribute that supports Block Bindings now supports Pattern Overrides too. You opt in per attribute via the server-side block_bindings_supported_attributes filter.

Here’s the shape for a custom block:

functions.php
<?php
add_filter(
    'block_bindings_supported_attributes',
    function( $supported_attributes, $block_name ) {
        if ( 'my-plugin/testimonial' === $block_name ) {
            $supported_attributes[] = 'quote';
            $supported_attributes[] = 'author';
        }
        return $supported_attributes;
    },
    10,
    2
);

Two details worth calling out:

  • The filter is keyed by block name and returns an array of attribute names the bindings system is allowed to bind to. Once an attribute is on that list, it becomes available for overrides (and for the rest of the Block Bindings API).
  • For dynamic blocks, bound values flow into your render_callback automatically. For static blocks with html, rich-text, or attribute sources, the HTML API handles the swap on save with no extra work. If a static block has unsourced attributes (or selectors the HTML API can’t follow), you may need a render_callback or a render_block filter to actually apply the bound value at render time.

This is the same opt-in shape we used last week, just on a different lever. Last week we used register_block_type_args to patch role: 'content' onto a third-party block so it would behave inside a contentOnly pattern. This week we use block_bindings_supported_attributes to opt a custom block’s attributes into Block Bindings so they can participate in overrides. WordPress is converging on a consistent model: blocks declare which surface is “the content,” and patterns layer reusable structure on top of those declarations.

Wrapping up

Three layers stack here, and they’re easier to keep straight when you name them out loud:

  1. Synced patterns give you one design with shared structure.
  2. Pattern overrides give you per-instance editable fields inside that shared structure.
  3. WP 7.0 extends that override surface to any block via Block Bindings, not just the core four.

Pair that with last week’s contentOnly-by-default for unsynced patterns and the editorial story is consistent across both pattern types. Editors get a focused, content-shaped editing experience by default. You decide exactly which surfaces are editable.

Happy coding!

Further reading

  1. Historically, synced patterns didn’t allow you to change any of their contents and were the same anywhere they were used. Pattern overrides make it possible to have your cake and eat it too. ↩︎


Leave a Reply

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