How to get and set post meta for core/navigation-link?

If it’s a menu item in a classic menu, then yes, you could use useEntityProp to get and set the menu item’s post meta, except that the post type is actually nav_menu_item and that you would need to manually add custom fields support to that post type.

const navMenuItemId     = 123;
const [ meta, setMeta ] = useEntityProp( 'postType', 'nav_menu_item', 'meta', navMenuItemId );

However, as for the core/navigation-link block, the props.attributes.id value is not actually the (classic) menu item’s post ID. It is instead the database ID, if any, of the linked resource, e.g. a Page ID if the resource was a Page at https://example.com/sample-page.

It should also be noted that the parent block, namely core/navigation, uses a non-public custom post type named wp_navigation, and the menu items (which are inner blocks of the Navigation block) are stored in the post content of a Navigation post (i.e. post of the wp_navigation type), and when a Navigation block is added to a post, the generated block markup would look like <!-- wp:navigation {"ref":502} /--> whereby 502 is the ID of a Navigation post.

  • You can edit/view the post by navigating to <your site URL>/wp-admin/site-editor.php?postId=502&postType=wp_navigation&canvas=edit.

  • Sample admin screen:

    Screenshot

Having said all that, it is unfortunately not possible to get the classic menu item’s post ID from the Navigation Link block’s markup, but these might help:

  • You can use the blocks.registerBlockType filter to add someboolean (and your other attributes) as attributes of the Navigation Link block, which means your attributes will be saved in the post content instead.

  • The above filter can also be used to add the ref attribute of the Navigation block as a context which can be consumed by the Navigation Link block.

    That way, you can, if you want to, get and set the Navigation post’s meta. But just like the nav_menu_item post type, you will need to manually add custom fields support to the wp_navigation post type.

  • There’s a block filter named blocks.navigation.__unstableMenuItemsToBlocks which can be used to get the menu item’s post ID, but only when a classic menu is imported via the editor. (screenshot)

    wp.hooks.addFilter(
        'blocks.navigation.__unstableMenuItemsToBlocks',
        'my-plugin/on-import-classic-menu',
        ( blocks, menuItems ) => {
            console.log( blocks, menuItems );
            /*
             * `blocks` is an object with 2 items, i.e. `innerBlocks` and `mapping`.
             * `mapping` is an object like so:
                {
                    // Each row is "<menu item's post ID>": "<block's clientId>", and
                    // corresponds to a `core/navigation-link` block.
                    "303": "b6fb470c-cc9a-4cd1-b93a-dbda6d705bde",
                    "304": "a7ee7b72-d5fa-4b64-9ea6-e3c64c89ee05",
                    "306": "aa9aa567-1084-4dc5-9f2b-b216eb321576",
                    "486": "99346d86-bbc9-497c-9fea-7e85401ad287"
                }
            */
    
            return blocks;
        }
    );
    

error code: 523