Does `viewScript` in `block.json` actually enqueue a js file?

If I have declared, viewScript in my block.json file. Do I need to enqueue the script manually within my register_block_type(); function also? (I didn't think it was necessary for 5.9?)

My Block.json

textdomain: postcode-pricing-wizard,
editorScript: file:./index.js,
viewScript: file:./view.js,
style: file:./style-index.css

My Problem

I've enqueued the script, as shown above, I can see a completed build directory and I can also see my block within the editor.

view.js However, isn't loading for me on my front-end? I'm not too sure why?

Unless I've misinterpreted the doc's Block Editor Handbook - Metadata

{ viewScript: file:./build/view.js }

// Block type frontend script definition. 
// It will be enqueued only when viewing the content on the front of the site.
// Since WordPress 5.9.0 (My WP Version - 5.9)

--

Here's my register_block_type() function just in case it's needed.

register_block_type( PPW_DIR_PATH . '/build/pricing-wizard-block/',
    array(
        'render_callback' = function( $attributes, $content ) {
            if(!is_admin()) {
                wp_localize_script( 'wp-block-ppw-postcode-pricing-wizard-js', 'data', ['ajax_url' = admin_url('admin-ajax.php')]);
            }

            ob_start();
            include_once plugin_dir_path( __FILE__ ) . '/includes/block-editor/pricing-wizard-block/views' . '/block.php';
            return ob_get_clean();
        },
    )
);

Topic block-editor Wordpress

Category Web


I tested this with WordPress 5.9.3 and @wordpress/scripts 22.5.0 and script does get enqueued. I think the original error was "viewScript": "file:./build/view.js" in block.json. Block.json should be placed in src directory, together with view script and they are copied in the build process to build directory. Afterwards, block is initialized from build directory.

i.e. for dynamic block logos (it has php for front end showing)

...
require 'logos/src/index.php';
register_block_type( "$dir/logos/build",
    ['render_callback' => 'render_logos'] );
...

in block.json:

...
"editorScript": "file:index.js",
"editorStyle": "file:index.css",
"style": "file:style-index.css",
"viewScript": "file:logos-front.js",
...

in package.json:

...
"start logos": "wp-scripts start --webpack-src-dir=logos/src --webpack-copy-php --output-path=./logos/build",
"build_logos": "wp-scripts build --webpack-src-dir=logos/src --webpack-copy-php --output-path=./logos/build",
...

--webpack-src-dir is only necessary because I have multi-block configuration - more blocks in same plugin. If you have only one block, it is not necessary, as long as you have standard directory naming and nesting conventions for single block


Note to self, rest-up and re-read the docs.

So it turns out that the answer is written in the docs, but rather obscurely. If you check out the Frontend Enqueueing section of the Block Editor Handbook, you'll see this statement.

Frontend Enqueueing #Frontend Enqueueing
Starting in the WordPress 5.8 release, it is possible to instruct WordPress to enqueue scripts and styles for a block type only when rendered on the frontend. It applies to the following asset fields in the block.json file:

- script
- viewScript (when the block defines render_callback during registration in PHP, then the block author is responsible for enqueuing the script)
- style

As it turns out I have defined a render_callback so I do need to manually enqueue my view.js script.

You know when you're just that tired you get tunnel vision. Yeah, this was one of those times. Anyway, thanks for reading. Figured I'd answer for anyone else that came along with a similar issue.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.