Question

I am following the "Store Post Meta with a Block" guide from the official Block Editor Handbook to add a custom post meta block using the supplied sample code (below). However, the block does not load and a Uncaught SyntaxError: Cannot use import statement outside a module error is displayed from the myguten.js file in the console when loading the block editor page.

How can I resolve this? Is the WordPress Block Editor Handbook code incorrect?

myguten-meta-block.php:

// register custom meta tag field
function myguten_register_post_meta() {
    register_post_meta( 'post', 'myguten_meta_block_field', array(
        'show_in_rest' => true,
        'single' => true,
        'type' => 'string',
    ) );
}
add_action( 'init', 'myguten_register_post_meta' );

function myguten_enqueue() {
    wp_enqueue_script(
        'myguten-script',
        plugins_url( 'myguten.js', __FILE__ ),
        array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-data', 'wp-core-data', 'wp-block-editor' )
    );
}
add_action( 'enqueue_block_editor_assets', 'myguten_enqueue' );

myguten.js:

import { registerBlockType } from '@wordpress/blocks';
import { TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { useBlockProps } from '@wordpress/block-editor';
 
registerBlockType( 'myguten/meta-block', {
    title: 'Meta Block',
    icon: 'smiley',
    category: 'text',
 
    edit( { setAttributes, attributes } ) {
        const blockProps = useBlockProps();
        const postType = useSelect(
            ( select ) => select( 'core/editor' ).getCurrentPostType(),
            []
        );
        const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
        const metaFieldValue = meta[ 'myguten_meta_block_field' ];
        function updateMetaValue( newValue ) {
            setMeta( { ...meta, myguten_meta_block_field: newValue } );
        }
 
        return (
            <div { ...blockProps }>
                <TextControl
                    label="Meta Block Field"
                    value={ metaFieldValue }
                    onChange={ updateMetaValue }
                />
            </div>
        );
    },
 
    // No information saved to the block
    // Data is saved to post meta via the hook
    save() {
        return null;
    },
} );

No correct solution

OTHER TIPS

You should use @wordpress/scripts so you can profit from modern JavaScript language features and JSX and transpile it to browser-compatible code. It's really not complicated to use.

Just install it via npm install @wordpress/scripts --save and than you can transpile your source file like this wp-scripts build src/myguten.js.js --output--path=js.

It's not only modern language features but versioning and dependency management that comes with it too. Readmore: https://medium.com/write-better-wordpress-code/properly-add-modern-javascript-to-gutenberg-14bde8679d83

I discovered this was occurring because I was using the supplied ESNext JavaScript code from the guide.

Although it is never once mentioned in the "Store Post Meta with a Block" guide, this page in a later section confirms the ESNext code must be "compiled" before it can be used.

Using the sample ES5 code from this page of the guide works.

( function ( wp ) {
    var el = wp.element.createElement;
    var registerBlockType = wp.blocks.registerBlockType;
    var TextControl = wp.components.TextControl;
    var useSelect = wp.data.useSelect;
    var useEntityProp = wp.coreData.useEntityProp;
    var useBlockProps = wp.blockEditor.useBlockProps;
 
    registerBlockType( 'myguten/meta-block', {
        title: 'Meta Block',
        icon: 'smiley',
        category: 'text',
 
        edit: function ( props ) {
            var blockProps = useBlockProps();
            var postType = useSelect( function ( select ) {
                return select( 'core/editor' ).getCurrentPostType();
            }, [] );
            var entityProp = useEntityProp( 'postType', postType, 'meta' );
            var meta = entityProp[ 0 ];
            var setMeta = entityProp[ 1 ];
 
            var metaFieldValue = meta[ 'myguten_meta_block_field' ];
            function updateMetaValue( newValue ) {
                setMeta(
                    Object.assign( {}, meta, {
                        myguten_meta_block_field: newValue,
                    } )
                );
            }
 
            return el(
                'div',
                blockProps,
                el( TextControl, {
                    label: 'Meta Block Field',
                    value: metaFieldValue,
                    onChange: updateMetaValue,
                } )
            );
        },
 
        // No information saved to the block
        // Data is saved to post meta via attributes
        save: function () {
            return null;
        },
    } );
} )( window.wp );
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top