6

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();
        },
    )
);
2
  • 1
    this too would be my expectation. I do notice you're trying to localise the admin-ajax.php files location, is there a reason you chose to use the legacy AJAX API instead of the modern REST API for AJAX actions? Are you using v5.9?
    – Tom J Nowell
    Commented Feb 21, 2022 at 23:39
  • @TomJNowell I chose the legacy version for ease of use. I'm more familiar with that version. I plan on revising in due course, but for now, I'm favouring speed in this particular project. I am currently using v5.9 yes.
    – Lewis
    Commented Feb 22, 2022 at 4:19

3 Answers 3

13

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. 👌👍

3
  • It seems that this is true, removing render_callback enqueues the script defined in viewScript. I just don't get what is reasoning behind that behavior?
    – Lovor
    Commented Apr 4, 2022 at 15:22
  • Yes, I've also miss looked that one at first :) One thing that still confuses me, is why are my scripts loaded in the front-end even if the block is not there? I thought it will be loaded conditionally.
    – Alexander
    Commented May 6, 2022 at 0:38
  • 3
    The name of the script registered is going to be what you call the block (name in block.json) + -view-script e.g. "name": "my-blocks/snazzy-block",. So in your callback function: wp_enqueue_script( 'my-blocks-snazzy-block-view-script' );
    – StephanieQ
    Commented Sep 3, 2022 at 16:36
7

EVEN NEWER EDIT: I actively participated as contributor in changing this rule. Starting from WordPress 6.1, viewScript will enqueue javascript even for dynamic blocks.

See trac #56470.

EDIT: I spoke yesterday with WP developers, viewScript does not actually enqueue script, but only registers it.

The reason is that in render_callback you might conclude that script is not necessary and not enqueue it. So, only for dynamic blocks, viewScript registers the script, while you must enqueue it in render_callback. For regular React blocks, script is automatically enqueued.


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",
...
5
  • 2
    If you have a multi-block plugin you can just create multiple folders in the src and wp-scripts will compile them automatically into separated folders. I'm using wp-scripts 22.5.0 and have a multi-directory plugin.
    – Alexander
    Commented May 6, 2022 at 0:35
  • @Alexander - thanks for comment. It did not work a year ago. I'll try this and if it works, I will update my answer
    – Lovor
    Commented May 7, 2022 at 10:18
  • @Lovor awesome to hear this has been changed. Thanks for contributing to this. 👌
    – Lewis
    Commented Nov 16, 2022 at 1:23
  • For me, experience with WordPress developing community was a good one so far. It really feels like it is a community project, and if you think something should be improved and you have good reasons for this, or you have a bugfix, you can contribute and this really works!
    – Lovor
    Commented Nov 16, 2022 at 21:49
  • @Lovor Thank you for getting out of bed, contributing to Gutenberg and, for taking the time to return to update your OP. Not all programmers wear capes
    – dj.cowan
    Commented Jun 19, 2023 at 13:04
1

I had a similar problem, but it was because my wp script build and wp script start used a custom entry point.

I had to add my viewScript manually to the build/start commands as in this example. Then in block.json I pointed the viewScript to the build folder, and it began enqueuing automatically:

"build:custom": "wp-scripts build index.js view.js --output-path=build"

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.