Real-Time Collaboration in the Block Editor

Real-time collaboration (RTC) in the blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. editor allows multiple users to edit content simultaneously by utilizing Yjs.

This dev notedev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase. covers three important aspects of the collaboration system that pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party. and theme developers should be aware of:

  • How metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. boxes affect collaboration mode
  • The sync.providers filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. for customized sync transport
  • Common issues when building plugins that can run in a collaborative environment

Collaboration is disabled when meta boxes are present

The Problem

Classic WordPress meta boxes are not synced by the real-time collaboration system. To avoid data loss, collaboration is disabled when meta boxes are detected on a post.

Locked post modal when someone takes over a post
Locked post modal when trying to take over a post

What developers need to know

To allow collaboration, consider migrating meta box functionality to registered post meta with show_in_rest set to true, and use sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. plugins or block-based alternatives that read from WordPress data stores.

For example:

register_post_meta( 'post', 'example_subtitle', [
	'show_in_rest' => true, // Required for syncing.  
	'single' => true,  
	'type' => 'string',
	'revisions_enabled' => true, // Recommended to track via revision history.
] );

For more details on migrating from meta boxes, see the Meta Boxes guide in the Block Editor Handbook.


The sync.providers filter: Customizing the sync transport layer

Overview

The @wordpress/sync package uses a provider-based architecture for syncing collaborative editing data. By default, WordPress ships with an HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. polling provider. The sync.providers filter allows plugins to replace or extend the transport layer. For example, a plugin could switch from HTTP polling to WebSockets for lower-latency collaboration.


How it works

The filter is applied during provider initialization:

const filteredProviderCreators = applyFilters(
'sync.providers',
getDefaultProviderCreators() // array of provider creators
);

A provider creator is a function that accepts a ProviderCreatorOptions object (containing the Yjs ydoc, awareness, objectType, and objectId) and returns a ProviderCreatorResult with destroy and on methods. The destroy method is called when the provider is no longer needed, and the on method allows the editor to listen for connection status events (connecting, connected, disconnected).


Example: WebSocket provider

The following example replaces the default HTTP polling provider with a WebSocket-based transport using the y-websocket library:

import { addFilter } from '@wordpress/hooks';
import { WebsocketProvider } from 'y-websocket';

/**
 * Create a WebSocket provider that connects a Yjs document
 * to a WebSocket server for real-time syncing.
 */
function createWebSocketProvider( { awareness, objectType, objectId, ydoc } ) {
	const roomName = `${ objectType }-${ objectId ?? 'collection' }`;
	const serverUrl = 'wss://example.com/';

	const provider = new WebsocketProvider(
		serverUrl,
		roomName,
		ydoc,
		{ awareness }
	);

	return {
		destroy: () => {
			provider.destroy();
		},
		on: ( eventName, callback ) => {
			provider.on( eventName, callback );
		},
	};
}

addFilter( 'sync.providers', 'my-plugin/websocket-provider', () => {
	return [ createWebSocketProvider ];
} );


What developers need to know

  • The sync.providers filter is only applied when real-time collaboration is enabled.
  • Return an empty array to disable collaboration entirely.
  • Return a custom array to replace the default HTTP polling provider with your own transport (e.g., WebSockets, WebRTC).

Common issues when building plugins compatible with real-time collaboration

When real-time collaboration is active, all connected editors share the same underlying data state via Yjs. Plugins that interact with post data, especially custom post meta, need to follow certain patterns to avoid sync issues

Syncing custom post meta values

In addition to being registered, custom meta field UIUI User interface must be consumed from the WordPress data store and passed to controlled input components.
Always derive the input value directly from the WordPress data store via useSelect. In addition, use value instead of defaultValue on input components so the input always reflects the current data store state.

const metaValue = useSelect(
	select => select( 'core/editor' ).getEditedPostAttribute( 'meta' )?.example_subtitle,
	[]
);

<input
	value={ metaValue || '' }
	onChange={ event => {
		editPost( { meta: { example_subtitle: event.target.value } } );
	} }
/>

Avoiding local component state for shared data

When building a plugin UI that reads from the WordPress data store, avoid copying that data into local ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. state with useState. This applies to any shared data, such as post meta or block attributes. Doing so disconnects your component from the shared collaborative state: updates from other clients will update the store, but your component won’t reflect them after the initial render, leading to stale or conflicting data.

Blocks with side effects on insertion

Custom blocks that trigger side effects on insertion will trigger that side effect for all connected collaborators, since block content syncs immediately upon insertion.

For example, instead of auto-opening a modal when a block is inserted, show a placeholder with a button that opens the modal on click. This ensures side effects are intentional and local to the user taking the action.


Credits

Props @czarate, @alecgeatches, @maxschmeling, @paulkevan, and @shekharwagh for building real-time collaboration in the block editor alongside @ingeniumed, and for technical review and proofreading of this dev note.

Parts of this work are derived from contributions made by @dmonad in this PR, and utilizes his Yjs library.

Props to @wildworks and @tyxla for proofreading this dev note.

#dev-notes, #dev-notes-7-0, #7-0

Call For Feedback: Increasing Value of Release Party Testing Phase

Every WordPress release party includes a phase dedicated to community testing. Contributors from around the world come together synchronously, run through a set of testing scenarios, and report the results in the #core SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel. It’s a great tradition and one of the most accessible ways to contribute to a WordPress release.

But as the process has evolved and the project has scaled over the years, some repeating pain points have become clear that are worth addressing. With WordPress 7.0 set to be released during Contributor Day at WordCamp Asia on April 9th, there’s a valuable opportunity to experiment with a large group of contributors in the same room. This feels like the right moment to ask the community for ideas.

This post is a call for feedback aimed at improving how release party testing works, both for those participating synchronously on release day and for contributors who want to keep testing after the party concludes.

What Makes Release Party Testing Great

Before getting into the areas to improve, it’s worth acknowledging why this part of the release process matters and what it gets right.

Release party testing is one of the easiest ways to get involved as a contributor. You only need to know how to update a WordPress site and run through a few basic scenarios that are outlined in the CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. Handbook. There’s no deep technical knowledge required. That low barrier to entry is not something to be sacrificed in pursuit of more structured or rigorous testing. Lowering barriers to contribution is one of the most important things an open sourceOpen Source Open Source denotes software for which the original source code is made freely available and may be redistributed and modified. Open Source **must be** delivered via a licensing model, see GPL. project can do, and any changes made here should make the process more approachable, not more intimidating.

With that in mind, here are some of the areas where there’s room to improve.

Current Pain Points

The channel can become difficult to follow

During the testing phase, the #core channel fills up quickly. For contributors whose first language isn’t English, a fast-moving channel can be especially overwhelming. And when off-topic messages or late test reports get mixed in, it becomes that much harder for everyone to keep up with what matters.

Testing scenarios lack release-specific context

A list of common scenarios to test is always shared. While these are frequently improved and are helpful as a starting point, they tend to be fairly generic (“test creating a new post”), without any guidance on what specifically changed in this release that a tester should be looking for or confirming. Without that context, it’s harder for testers to know where to focus their attention or what a successful test actually looks like for a given release.

It’s not always clear what was tested or how

Testing reports typically include details like installation type, method of updating, version of WP being updated from, PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher version, which is all useful. But there’s often less clarity about how specific things were tested. What steps did the tester follow? What browser were they using? Were they testing as an adminadmin (and super admin), an editor, or a subscriber? That level of detail can matter a lot when trying to triagetriage The act of evaluating and sorting bug reports, in order to decide priority, severity, and other factors. or reproduce a reported issue.

It’s hard to gauge the overall coverage of testing

When it’s unclear how many contributors are actively running through scenarios versus following along, it’s difficult to know how thoroughly the release has been tested. Without that visibility, it’s hard to identify gaps in coverage or know which environments and workflows still need attention.

Testing reports continue after the testing phase ends

The emcee running the release process announces when the testing portion has concluded and asks that only failures be reported going forward. Despite this, testing reports continue to come in, which disrupts the coordination work that follows. This is a process and communication challenge as much as anything, but it’s worth addressing directly.

There’s no clear path forward after the party ends

This is probably the most significant gap for contributors. Once the release party concludes, all of the testing feedback that was shared becomes another message buried within the Slack archives. There’s no clean summary of what was tested, what was found, and what still needs attention. And there’s no obvious next step for contributors who want to keep testing the release after it ships.

Testing shouldn’t stop at the release party. Every new major version of WordPress deserves continued testing across a broader range of environments, configurations, and workflows than any single party can cover.

Goals

With all of that in mind, here’s what improvements to this process should aim to accomplish:

  • Make better use of everyone’s valuable time. Contributors are generous in showing up for release parties. The process should respect that.
  • Test more scenarios that are relevant to a given release. Testers should know what changed and what to look for, not just what to click.
  • Keep the release process on track. When off-topic messages or late test reports flood the channel, critical information can get lost at exactly the wrong moment.
  • Make it more clear exactly what was tested and how. Structured reporting, even in a lightweight form, leads to more actionable results.
  • Provide contributors with a clear path to continue contributing. The release party should be a starting point, not the end of the road.
  • Connect release party testing to the broader testing cycle. Pre-release calls for testing cover a lot of ground, and the party should build on that work rather than exist in isolation from it.
  • Leverage tools that contributors already know and use. Building on existing and familiar tools, such as Playground and the Test Reports plugin, reduces friction, helps standardize the process, and creates a more consistent experience.

None of these goals should come at the cost of making testing harder to participate in as that’s not a compromise worth making.

An Opportunity at WordCampWordCamp WordCamps are casual, locally-organized conferences covering everything related to WordPress. They're one of the places where the WordPress community comes together to teach one another what they’ve learned throughout the year and share the joy. Learn more. Asia

WordPress 7.0 is planned to be released during Contributor DayContributor Day Contributor Days are standalone days, frequently held before or after WordCamps but they can also happen at any time. They are events where people get together to work on various areas of https://make.wordpress.org/ There are many teams that people can participate in, each with a different focus. https://2017.us.wordcamp.org/contributor-day/ https://make.wordpress.org/support/handbook/getting-started/getting-started-at-a-contributor-day/. at WordCamp Asia on April 9th. Having a large group of contributors physically present in the same room is a genuinely rare opportunity. Experiments that are difficult to run when 100% of participants are distributed become a lot more practical when a meaningful portion of the group is co-located. That makes the 7.0 release party an ideal time to create a plan and try out something new.

Summary

This post is an open call for any ideas. There’s no one perfect answer or solution, and it may take several releases to find what works best. What adjustments should be made to the testing phase of a release party? Are there practices from other open source projects or testing communities worth borrowing from?

Conversation Starters

Here are a few rough ideas to get the conversation started:

  • A “How to Test During a Release Party” course on Learn WordPress: A short course or guide on Learn WordPress that walks first-time participants through what to expect, how to run through a scenario, and what makes a useful test report. Helps contributors show up prepared rather than figuring it out on the fly.
  • Pair newer contributors with more experienced ones during the testing phase: The experienced contributor can help guide the approach, model what a useful report looks like, and answer questions in real time. This should result in higher quality results while naturally supporting onboarding at the same time.
  • End each release party with a clear “what’s next”: Close out the testing phase with a specific, actionable next step for contributors who want to keep going.
  • A designated release party testing board: A shared, visible checklist of the specific scenarios that need to be covered during the party. This is updated in real time as contributors claim and complete each one. Rather than everyone independently deciding what to test, the board makes it clear what’s been covered and what still needs attention, helping the group collectively ensure nothing important gets missed.

Please leave your thoughts and ideas in the comments!

Props to @annezazu, @jeffpaul, and @karmatosed for reviewing this post.


Claude (Sonnet 4.6) was used to create an initial draft from a detailed list of pain points, pros, cons, and surrounding context, and also to perform proofreading.

#feedback

Pseudo-element support for blocks and their variations in theme.json

WordPress 7.0 adds support for pseudo-class selectors (:hover, :focus, :focus-visible, and :active) directly on blocks and their style variations in theme.json. Previously, this was only possible for HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. elements like button and link under the styles.elements key. BlockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience.-level interactive states could only be achieved through custom CSSCSS Cascading Style Sheets..

Variation-level pseudo-selectors

Block style variations can also define interactive states. This is particularly useful for variations like “Outline” that have distinct visual styles requiring different hover behaviors:

{
    "styles": {
        "blocks": {
            "core/button": {
                "variations": {
                    "outline": {
                        "color": {
                            "background": "transparent",
                            "text": "currentColor"
                        },
                        ":hover": {
                            "color": {
                                "background": "currentColor",
                                "text": "white"
                            }
                        }
                    }
                }
            }
        }
    }
}

  • This is a theme.json-only APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.. There is no new UIUI User interface in Global Styles for these states in 7.0. Work on this is happening at #38277 and will be added in a future release.
  • The supported pseudo-selectors for core/button are: :hover, :focus, :focus-visible, and :active. Any others will be ignored.
  • Pseudo-selectors defined at the block level and at the variation level are independent — you can define both without conflictconflict A conflict occurs when a patch changes code that was modified after the patch was created. These patches are considered stale, and will require a refresh of the changes before it can be applied, or the conflicts will need to be resolved..

See #64263 for more details

Props to @scruffian, @onemaggie for the implementation

Props to @mikachan, @scruffian for technical review and proofreading.

#7-0, #dev-notes, #dev-notes-7-0

Announcing the Featured Plugins Experiment

I pitched this to Matt directly and have been given the go ahead to pave the way here. This post begins that process and documents the Featured Plugins experiment currently underway on WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/. The goal is to surface newer plugins in the directory that meet a defined quality bar but have limited visibility. Eight plugins are selected every two weeks.

Eligibility
To be considered, a pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party. must meet all of the following baseline requirements:

Active installs: fewer than 10,000
Age: listed in the directory for 12 months or less
No open security vulnerabilities
Compatible with the current major releasemajor release A release, identified by the first two numbers (3.6), which is the focus of a full release cycle and feature development. WordPress uses decimaling count for major release versions, so 2.8, 2.9, 3.0, and 3.1 are sequential and comparable in scope. of WordPress
Updated within the last 6 months

Selection Criteria
Plugins that pass the eligibility requirements are evaluated against three categories of criteria.

Technical standards
Code is human-readable and follows WordPress coding standardsWordPress Coding Standards The Accessibility, PHP, JavaScript, CSS, HTML, etc. coding standards as published in the WordPress Coding Standards Handbook. May also refer to The collection of PHP_CodeSniffer rules (sniffs) used to format and validate PHP code developed for WordPress according to the PHP coding standards.
Proper use of escaping, sanitization, and nonces
No unnecessary bundling of libraries or WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. functionality
Plugin readme accurately describes what the plugin does

Ecosystem fit
Addresses a problem not already well-served by existing plugins
Provides functionality with genuine utility to WordPress users

Developer engagement
Developer is responsive in the support forums
UXUX User experience reflects care and intentionality in the implementation

How Decisions Are Made
Plugin selection is currently handled by Nick Hamze. The process and governance around selections will be reassessed as the experiment develops.

How Plugins Are Considered
All plugins that meet the eligibility requirements are automatically included in the pool for consideration. No submission is required.

Plugin authors who want to provide additional context about their plugin — or make a case for its inclusion — can do so in the #featuredplugins channel on the Make WordPress SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/..

Tracking Progress
This experiment is tracked openly. Feedback on the criteria, the process, or specific selections can be shared in the #featuredplugins Slack channel. The process and governance around selections will be reassessed as the experiment develops. Right now, the aim is to experiment first with a small scope to ensure it’s meaningful for end users, plugin authors, and contributors. As the work evolves, more documentation and any necessary process can be added so future contributors can join.

Breadcrumb block filters

WordPress 7.0 introduces a new Breadcrumbs blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. that can be placed once — such as in a theme’s headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. — and automatically reflects the site’s navigation hierarchy.

Image
Breadcrumbs block in a header template part using Twenty Twenty-Five theme, here showing the trail for a child page

Two filters provide developers with control over the breadcrumb trail output.

block_core_breadcrumbs_items

This filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. allows developers to modify, add, or remove items from the final breadcrumb trail just before rendering. Each item is an array with three properties:

  1. label (string) — the breadcrumb text.
  2. an optional url (string) — the breadcrumb link URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org.
  3. an optional allow_html (bool) — whether to allow HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. in the label. When true, the label will be sanitized with wp_kses_post(), allowing only safe HTML tags. When false or omitted, all HTML will be escaped with esc_html().

Example: Prepend a custom breadcrumb item

  add_filter( 'block_core_breadcrumbs_items', function ( $breadcrumb_items ) {
        array_unshift( $breadcrumb_items, array(
                'label' => __( 'Shop', 'myplugin' ),
                'url'   => home_url( '/shop/' ),
        ) );

        return $breadcrumb_items;
  } );

block_core_breadcrumbs_post_type_settings

When a post type has multiple taxonomies or when a post is assigned to multiple terms within a taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies., there could be numerous ways to construct the breadcrumbs trail. For example in a post that has both categories and tags a user might want to show in the breadcrumbs trail the categories (default), the tags and/or select a specific tagtag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.).

This filter controls which taxonomy and terms appear in the Breadcrumbs block trail for posts that use taxonomy-based breadcrumbs. It applies to non-hierarchical post types (e.g., posts, products) or hierarchical post types when the block’s “Prefer taxonomy terms” setting is enabled (under advanced settings). It does not affect hierarchical ancestor-based trails (e.g., parent/child pages).

The filter receives three parameters:

  • $settings (array) — an empty array by default. Callbacks should populate the array and return it with the following optional keys:
    • taxonomy (string) — taxonomy slug to use for breadcrumbs.
    • term (string) — term slug to prefer when the post has multiple terms in the selected taxonomy.
  • $post_type (string) — the post type slug.
  • $post_id (int) — the post ID, enabling per-post customization.

Fallback behavior

  • If the preferred taxonomy doesn’t exist or has no terms assigned, fall back to the first available taxonomy with terms assigned.
  • If the preferred term doesn’t exist or isn’t assigned to the post, fall back to the first term
  • If the post has only one term, that term is used regardless of setting

Example 1: Set a preferred taxonomy and term per post type

add_filter( 'block_core_breadcrumbs_post_type_settings', function( $settings, $post_type ) {
	if ( $post_type === 'post' ) {
		$settings['taxonomy'] = 'category';
		$settings['term'] = 'news';
	}
	if ( $post_type === 'product' ) {
		$settings['taxonomy'] = 'product_tag';
	}
	return $settings;
}, 10, 2 );

Example 2: Choose a specific term per post

add_filter( 'block_core_breadcrumbs_post_type_settings', function ( $settings, $post_type, $post_id ) {
	if ( $post_type !== 'post' ) {
		return $settings;
	}
	
	$terms = get_the_terms( $post_id, 'category' );

	if ( $terms ) {
		$settings['taxonomy'] = 'category';
		$settings['term']     = end( $terms )->slug;
	}

	return $settings;
}, 10, 3 );

See GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ pull requests: 74169, 73283, 74170.

Props to @karolmanijak, @ntsekouras for the implementation.

Props to @karolmanijak for technical review.

Props to @mcsf for copy review.

#dev-notes, #7-0

Customisable Navigation Overlays in WordPress 7.0

WordPress 7.0 introduces Customisable Navigation Overlays, giving site owners full control over their mobile navigation menus using the blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. editor.

Previously, when a visitor tapped a hamburger menu icon on a mobile device, WordPress displayed a fixed default overlay with no support for customisation. The design, layout, and content were locked.

Customisable Navigation Overlays remove this restriction entirely — any overlay can now be built from blocks and patterns in the Site Editor. This includes a dedicated Navigation Overlay Close block for placing and styling a close button anywhere within the overlay.

How overlays work

Navigation overlays are implemented as template parts using a new navigation-overlay template part area, managed principally through the Navigation block’s overlay controls in the Site Editor. Because they are template parts, they can also be found and edited via the Patterns section in the Site Editor sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme.. Each overlay is assigned to a Navigation block — while the same overlay can be referenced by more than one, a one-to-one relationship is the most common pattern.

What goes inside an overlay is entirely up to the author. As a standard block canvas, it can contain any block — navigation, social icons, a search field, a site logo, calls to action…or any combination! A Navigation block is the typical inclusion but is not a requirement. Because overlays only function correctly when rendered by a Navigation block, overlay template parts are intentionally excluded from the general block inserter — this prevents them from being inserted accidentally into other parts of a template.

The feature is opt-in: by default, the Navigation block continues to use the standard overlay behaviour from previous versions of WordPress. A custom overlay can be activated in three ways:

  • Creating a new overlay — via the Overlays section in the Navigation block’s sidebar controls in the Site Editor
  • Selecting an existing overlay — from the same controls, choosing from any overlays already created or bundled with the active theme
  • Theme pre-assignment — a theme can reference a bundled overlay directly in the Navigation block markup (covered in the developer section below)

For theme developers: bundling overlays with your theme

Themes can ship pre-built navigation overlays so they are available as soon as the theme is activated. The recommended approach is to provide both a default overlay template part and a set of overlay patterns.

Template parts vs patterns

Understanding the distinction helps decide how to structure an overlay offering:

  • template part is the overlay itself — the component that gets rendered when a Navigation block uses an overlay. Shipping a template part means a ready-to-use overlay is available from the moment the theme is activated.
  • Patterns are design options that appear in the Design tab when editing a navigation overlay in the Site Editor. Selecting a pattern replaces the current overlay content with the pattern’s block markup, letting users switch between distinct designs.

A patterns-only approach is also valid — useful when a theme wants to offer design options without pre-applying an overlay automatically. In this case, users create a new overlay via the Navigation block’s controls and pick from the theme’s patterns as a starting point.

Updating your Theme

1. Register the template part in theme.json

Registering the template part in theme.json is required. Without it, the template part is assigned the uncategorized area and will not be recognised by the Navigation block as an overlay.

Add an entry to the templateParts array, setting area to navigation-overlay:

{
    "templateParts": [
        {
            "area": "navigation-overlay",
            "name": "my-custom-overlay",
            "title": "My Custom Overlay"
        }
    ]
}

2. Create the template part file

Create the corresponding HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. file in the theme’s parts/ directory. The filename should match the name value from theme.json.

It is strongly recommended to include the Navigation Overlay Close block within the overlay. If it is omitted, WordPress will automatically insert a fallback close button on the frontend for accessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility) and usability reasons — but that button may not match the overlay’s design or be positioned as expected. Including it explicitly gives full control over its appearance and placement.

<!-- parts/my-custom-overlay.html -->
<!-- wp:group {"layout":{"type":"flex","orientation":"vertical"}} -->
<div class="wp-block-group">
    <!-- wp:navigation-overlay-close /-->
    <!-- wp:navigation {"layout":{"type":"flex","orientation":"vertical"}} /-->
</div>
<!-- /wp:group -->

3. Register overlay patterns

Overlay patterns are registered using register_block_pattern(). Setting blockTypes to core/template-part/navigation-overlay scopes the pattern so it only appears when editing a navigation overlay template part — not in the general inserter.

register_block_pattern(
    'my-theme/navigation-overlay-default',
    array(
        'title'      => __( 'Default Overlay', 'my-theme' ),
        'categories' => array( 'navigation' ),
        'blockTypes' => array( 'core/template-part/navigation-overlay' ),
        'content'    => '<!-- wp:group {"layout":{"type":"flex","orientation":"vertical"}} -->
<div class="wp-block-group">
    <!-- wp:navigation-overlay-close /-->
    <!-- wp:navigation {"layout":{"type":"flex","orientation":"vertical"}} /-->
</div>
<!-- /wp:group -->',
    )
);

4. Pre-configuring the Navigation block (optional)

A theme can optionally pre-configure a Navigation block to reference a specific overlay by setting the overlay attribute in the block markup. The value should be the template part slug only — without a theme prefix:

<!-- wp:navigation {"overlay":"my-custom-overlay"} /-->

Using the slug only — without a theme prefix — is important for future compatibility: WordPress plans to allow template parts to persist across theme switches, and a theme-prefixed identifier would break that. This follows the same convention as header and footer template parts.

The overlay attribute is entirely optional — users can select or change the overlay at any time using the Navigation block’s sidebar controls.

Known limitations

Template parts and theme switching

Navigation overlay template parts are currently tied to the active theme. Custom overlays will not be preserved if the active theme is switched. This is a known limitation tracked in gutenberg#72452.

Overlays are full-screen only

In this initial release, navigation overlays are always rendered full-screen. Non-full-screen overlay styles (such as a sidebar drawer) are not yet supported. This requires implementing overlays as a true <dialog> element — including support for clicking outside to close — which is planned for a future release.

Not a generic popup or dialog

Navigation Overlays are intentionally scoped to the Navigation block and are not designed as a general-purpose popup or dialog implementation. For broader use cases — such as modal dialogs triggered by arbitrary content — a dedicated Dialog block is in development and tracked in gutenberg#61297.

Questions and feedback

Until now, the mobile navigation overlay has been one of the few remaining areas of a block theme that couldn’t be designed in the Site Editor. Navigation Overlays change that. An overlay can contain anything blocks can express — a simple menu with a styled close button, a full-screen layout with the site logo and a call to action, or a content-rich experience that turns the mobile menu into a destination in its own right.

There is a lot of creative space here, and seeing what the community builds with it will be exciting.

Questions are welcome in the comments below.

Further reading


Props @onemaggie for implementation contributions and technical review, @mikachan, @jeryj @scruffian for proofreading, and @mmcalister, whose Ollie Menu Designer pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party. helped validate community demand for this functionality.

#7-0, #dev-notes, #navigation

Changes to the Interactivity API in WordPress 7.0

New watch() function

WordPress 7.0 introduces a watch() function in the @wordpress/interactivity package. It subscribes to changes in any reactive value accessed inside a callback, re-running the callback whenever those values change.

Currently, the Interactivity APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. provides data-wp-watch as a directive tied to a DOM element’s lifecycle for reacting to state changes. However, there is no programmatic API to observe those changes independently of the DOM, for example, to run side effects at the store level, set up logging, or synchronize state between stores. The watch() function fills this gap.

import { store, watch } from '@wordpress/interactivity';

const { state } = store( 'myPlugin', {
    state: {
        counter: 0,
    },
} );

// Runs immediately and re-runs whenever `state.counter` changes.
watch( () => {
    console.log( 'Counter is ' + state.counter );
} );

The function returns an unwatch callback that stops the watcher:

const unwatch = watch( () => {
    console.log( 'Counter is ' + state.counter );
} );

// Later, to stop watching:
unwatch();

The callback can also return a cleanup function. This cleanup runs before each re-execution and when the watcher is disposed of via unwatch():

const unwatch = watch( () => {
    const handler = () => { /* ... */ };
    document.addEventListener( 'click', handler );

    return () => {
        document.removeEventListener( 'click', handler );
    };
} );

See #75563 for more details.

Props to @luisherranz for the implementation.

Deprecated state.navigation properties in core/router

The state.navigation.hasStarted and state.navigation.hasFinished properties in the core/router store were internal implementation details used for the loading bar animation. These were never intended to be part of the public API.

Starting in WordPress 7.0, accessing state.navigation from the core/router store is deprecated and will trigger a console warning in development mode (SCRIPT_DEBUG). Direct access will stop working in a future version of WordPress. An official mechanism for tracking navigation state will be introduced in WordPress 7.1.

See #70882 for more details.

Props to @yashjawale for the implementation.

state.url from core/router is now populated on the server

Previously, state.url in the core/router store was initialized on the client by setting it to window.location.href. This meant the value was undefined until the @wordpress/interactivity-router module finished loading asynchronously, requiring developers to guard against that initial undefined state and filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. out the subsequent initialization to avoid reacting to it as an actual navigation.

Starting in WordPress 7.0, this value is populated on the server during directive processing, meaning its value doesn’t change until the first client-side navigation occurs.

This makes it possible to combine watch() and state.url to reliably track client-side navigations, for example, to send analytics on each virtual page view:

import { store, watch } from '@wordpress/interactivity';

const { state } = store( 'core/router' );

watch( () => {
    // This runs on every client-side navigation.
    sendAnalyticsPageView( state.url );
} );

See #10944 for more details.

Props to @luisherranz for the implementation.

#7-0, #dev-notes, #dev-notes-7-0, #interactivity-api

DataViews, DataForm, et al. in WordPress 7.0

Previous cycle: WordPress 6.9.

This is a summary of the changes introduced in the “dataviews space” during the WordPress 7.0 cycle from the APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. perspective. They have been posted in the corresponding iteration issue as well. To follow what’s next, subscribe to the iteration issue for WordPress 7.1.

The changes listed here include 166 contributions by 35 unique authors across the community during the past 4.5 months (since October 17th, 2025).

Continue reading

#7-0, #dev-notes, #dev-notes-7-0

Dev Chat Agenda – March 4, 2026

The next WordPress Developers Chat will take place on Wednesday, March 4, 2026, at 15:00 UTC in the core channel on Make WordPress Slack.

The live meeting will focus on the discussion for upcoming releases, and have an open floor section.

The various curated agenda sections below refer to additional items. If you have ticketticket Created for both bug reports and feature development on the bug tracker. requests for help, please continue to post details in the comments section at the end of this agenda or bring them up during the dev chat.

Announcements 📢

WordPress 7.0 Updates

  • 7.0 Beta 2 was released on February 26th.
  • BetaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. 3 is scheduled for March 5th at 14:00 UTC in the #core SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel.
  • 7.0 bug scrubs continue twice a week in the #core Slack channel.
  • New Dev Notesdev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase.:

General

Discussions 💬

The discussion section of the agenda is for discussing important topics affecting the upcoming release or larger initiatives that impact the CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. Team. To nominate a topic for discussion, please leave a comment on this agenda with a summary of the topic, any relevant links that will help people get context for the discussion, and what kind of feedback you are looking for from others participating in the discussion.

Open floor  🎙️

Any topic can be raised for discussion in the comments, as well as requests for assistance on tickets. Tickets in the milestone for the next major or maintenance release will be prioritized.

Please include details of tickets / PRs and the links in the comments, and indicate whether you intend to be available during the meeting for discussion or will be async.

Props to @audrasjb for collaboration and review.

#7-0, #agenda, #dev-chat

PHP-only block registration

Developers can now create simple blocks using only PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher. This is meant for blocks that only need server-side rendering and aren’t meant to be highly interactive. It isn’t meant to replace the existing client-side paradigm, nor is it meant to ever be as featureful! However, this APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. could help developers avoid extra complexity and could thus foster blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. adoption, especially in classic themes or server-driven workflows.

To use it, call register_block_type with the new autoRegister flag. Note that a render_callback function must also be provided:

function gutenberg_register_php_only_blocks() {
    register_block_type(
        'my-plugin/example',
        array(
            'title'           => __( 'My Example Block', 'myplugin' ),
            'attributes'      => array(
                'title'   => array(
                    'label'   => __( 'Title', 'myplugin' ),
                    'type'    => 'string',
                    'default' => 'Hello World',
                ),
                'count'   => array(
                    'label'   => __( 'Count', 'myplugin' ),
                    'type'    => 'integer',
                    'default' => 5,
                ),
                'enabled' => array(
                    'label'   => __( 'Enabled?', 'myplugin' ),
                    'type'    => 'boolean',
                    'default' => true,
                ),
                'size'    => array(
                    'label'   => __( 'Size', 'myplugin' ),
                    'type'    => 'string',
                    'enum'    => array( 'small', 'medium', 'large' ),
                    'default' => 'medium',
                ),
            ),
            'render_callback' => function ( $attributes ) {
                return sprintf(
                    __( '<p>%s: %d items (%s)</p>', 'myplugin' ),
                    esc_html( $attributes['title'] ),
                    $attributes['count'],
                    $attributes['size']
                );
            },
            'supports'        => array(
                'autoRegister' => true,
            ),
        )
    );
}

add_action( 'init', 'gutenberg_register_php_only_blocks' );

These blocks will automatically appear in the editor without requiring any JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. registration, and, wherever possible, the editor will automatically generate controls in the Inspector Controls sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. to allow users to edit block attributes:

Image

Note that controls will not be generated for attributes with the local role or for attributes whose types are not supported.

See #64639 for more details.

Props to @priethor for the implementation.
Props to @wildworks for reviewing this dev notedev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase..

#dev-notes, #7-0