Issue TL;DR

I have a block that updates meta values, but when I click 'update', the values are not saved for the post. Additionally, the meta values I get from useEntityProp load as an object with meta key/values, but turns into an empty array when Update is clicked. If I reload the post, old values are still there, but new values are not.

Not sure if i am getting/setting meta incorrectly, but even the WP MetaBox Demo code has the same issue.

Issue Overview:

I'm working on adding a Meta Block in Gutenberg for a custom post type that I register via a plugin. I've done a lot of custom stuff, but after many hours of banging my head on my desk, I just copied over the demo from the WP MetaBox Demo, and still have the same issue.

I'm getting meta via:

const [ meta, setMeta ] = useEntityProp( 'postType', 'post-type-name', 'meta' );

If I console.log(meta), I get an a key/value object with the expected meta. When I use the demo from the link, the object is {myguten_meta_block_field: ''}

If I enter content into a TextControl, I can see the meta variable is now an object with the expected key/value pair ({myguten_meta_block_field: 'Text I Typed'}). Everything is great.

Then, I click "Update"...

The meta variable is now logging as an empty array []. The value I entered in the TextControl field is still in the Text field (and the meta variable goes to a key/value object again as soon as I type more into it).

If I reload, there is no change to the meta value, the field is empty. So the meta update did not stick. If there are other elements that had meta values in them, those field values are wiped.

Just to note, I tried converting from useEntityProp to useSelect/useDispatch (with editPost), and the same issue happens.



add_action( 'init', [$this, 'register_events_meta'] );

function register_events_meta() {

    register_post_meta( '[CPT_NAME]', 'myguten_meta_block_field', array(
      'show_in_rest' => true,
      'single' => true,
      'type' => 'string',
    ) );

Block JS:

import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import metadata from './block.json';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { TextControl } from '@wordpress/components';

registerBlockType( metadata.name, {
  edit: () => {
      const blockProps = useBlockProps();

      const [ meta, setMeta ] = useEntityProp( 'postType', '[CPT_NAME]', 'meta' );

      const metaFieldValue = meta[ 'myguten_meta_block_field' ];

      const updateMetaValue = ( newValue ) => {
          setMeta( { ...meta, myguten_meta_block_field: newValue } );


      return (
          <div { ...blockProps }>
                label="Meta Block Field"
                value={ metaFieldValue }
                onChange={ updateMetaValue }

  // No information saved to the block.
  // Data is saved to post meta via the hook.
  save: () => {
      return null;
} );

The Custom Post type registration has custom-fields in the supports array.

If there is anything else that I can share, let me know! Hopefully its just something simple that I'm not seeing!

Cheers Shaun

1 Answer 1


So, in my case, the answer was simple, though it took a long time to find. Just in case anyone else ever has this issue, here is what solved it for me:

I was calling the register_post_meta in a file that was only being included if is_admin() returns true (this is a plugin metabox conversion, so there are some admin-only assets being called, etc)

Long story short: meta fields were being registered in the block editor because is_admin() returns true, but when the request was sent to REST, is_admin() is false, so the meta fields were not being registered, and an empty array was returned.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.