This is a brief document detailing how meta box support works in the block editor. With the superior developer and user experience of blocks, especially once block templates are available, porting PHP meta boxes to blocks is highly encouraged! See the Meta Block tutorial for how to store post meta data using blocks.
Before converting meta boxes to blocks, it may be easier to test if a meta box works with the block editor, and explicitly mark it as such.
If a meta box doesn’t work with the block editor, and updating it to work correctly is not an option, the next step is to add the
__block_editor_compatible_meta_boxargument to the meta box declaration:
add_meta_box( 'my-meta-box', 'My Meta Box', 'my_meta_box_callback', null, 'normal', 'high', array( '__block_editor_compatible_meta_box' => false, ) );
WordPress won’t show the meta box but a message saying that it isn’t compatible with the block editor, including a link to the Classic Editor plugin. By default,
After a meta box is converted to a block, it can be declared as existing for backward compatibility:
add_meta_box( 'my-meta-box', 'My Meta Box', 'my_meta_box_callback', null, 'normal', 'high', array( '__back_compat_meta_box' => true, ) );
When the block editor is used, this meta box will no longer be displayed in the meta box area, as it now only exists for backward compatibility purposes. It will continue to display correctly in the classic editor.
On each block editor page load, we register an action that collects the meta box data to determine if an area is empty. The original global state is reset upon collection of meta box data.
It will run through the functions and hooks that
post.php runs to register meta boxes; namely
Meta boxes are filtered to strip out any core meta boxes, standard custom taxonomy meta boxes, and any meta boxes that have declared themselves as only existing for backward compatibility purposes.
Then each location for this particular type of meta box is checked for whether it is active. If it is not empty a value of true is stored, if it is empty a value of false is stored. This meta box location data is then dispatched by the editor Redux store in
Ideally, this could be done at instantiation of the editor and help simplify this flow. However, it is not possible to know the meta box state before
admin_enqueue_scripts, where we are calling
initializeEditor(). This will have to do, unless we want to move
initializeEditor() to fire in the footer or at some point after
admin_head. With recent changes to editor bootstrapping this might now be possible. Test with ACF to make sure.
When rendering the block editor, the meta boxes are rendered to a hidden div
The Redux store will hold all meta boxes as inactive by default. When
INITIALIZE_META_BOX_STATE comes in, the store will update any active meta box areas by setting the
isActive flag to
true. Once this happens React will check for the new props sent in by Redux on the
MetaBox component. If that
MetaBox is now active, instead of rendering null, a
MetaBoxArea component will be rendered. The
MetaBox component is the container component that mediates between the
MetaBoxArea and the Redux Store. If no meta boxes are active, nothing happens. This will be the default behavior, as all core meta boxes have been stripped.
When the component renders it will store a reference to the meta boxes container and retrieve the meta boxes HTML from the prefetch location.
When the post is updated, only meta box areas that are active will be submitted. This prevents unnecessary requests. No extra revisions are created by the meta box submissions. A Redux action will trigger on
REQUEST_POST_UPDATE for any active meta box. See
REQUEST_META_BOX_UPDATES action will set that meta box’s state to
isUpdating prop will be sent into the
MetaBoxArea and cause a form submission.
When the meta box area is saving, we display an updating overlay, to prevent users from changing the form values while a save is in progress.
An example save url would look like:
This url is automatically passed into React via a
_wpMetaBoxUrl global variable.
This page mimics the
post.php post form, so when it is submitted it will fire all of the normal hooks and actions, and have the proper global state to correctly fire any PHP meta box mumbo jumbo without needing to modify any existing code. On successful submission, React will signal a
handleMetaBoxReload to remove the updating overlay.
Most PHP meta boxes should continue to work in the block editor, but some meta boxes that include advanced functionality could break. Here are some common reasons why meta boxes might not work as expected in the block editor:
- Plugins relying on selectors that target the post title, post content fields, and other metaboxes (of the old editor).
- Plugins relying on TinyMCE’s API because there’s no longer a single TinyMCE instance to talk to in the block editor.
- Plugins making updates to their DOM on “submit” or on “save”.
Please also note that if your plugin triggers a PHP warning or notice to be output on the page, this will cause the HTML document type (