Wordpress - Load CSS/Javascript in frontend conditionally if block is used

Well, the styles and scripts you register in your php register_block_type call should only be loaded when the block is in use if i recall correctly.

If you want to load additional scripts or styles to be enqueued only if there is a block of type "my-awesome/block-type", you can use the has_block function in your wp_enqueue_scripts function like this:

add_action('wp_enqueue_scripts','enqueue_if_block_is_present');

function enqueue_if_block_is_present(){
  if(is_singular()){
     //We only want the script if it's a singular page
     $id = get_the_ID();
     if(has_block('my-awesome/block-type',$id)){
        wp_enqueue_script('my-awesome-script',$path_of_script,$needed_scripts,$version_of_script,$load_in_footer);
     }
  }
}

If you also want the script to be loaded on multiple views as well (like category archive or the blog page), you can hook into the the_content filter and enqueue the script there:

add_filter('the_content','enqueue_my_awesome_script_if_there_is_block');

function enqueue_my_awesome_script_if_there_is_block($content = ""){
  if(has_block('my-awesome/block-type')){
        wp_enqueue_script('my-awesome-script',$path_of_script,$needed_scripts,$version_of_script,true);
   //Be aware that for this to work, the load_in_footer MUST be set to true, as 
   //the scripts for the header are already echoed out at this point
     }
   return $content;
}

Happy Coding!


Another way is to enqueue them inside the block's render_callback() function.

register_block_type( 'mkaz/test-block', array(
    'editor_script'   => 'mkaz-test-block-script',
    'render_callback' => function( $attribs, $content ) {
        wp_enqueue_script( 'mkaz-test-block-client-asset' );
        return $content;
    }
) );

In the past it was invalid to enqueue stylesheets outside of <head>, but that's supported by the spec now.

x-ref: https://github.com/WordPress/gutenberg/issues/21838


Thanks @kuchenundkakao for pointing me into the right direction. I'm still answering my own question as I want to give some more context for others that may stumble upon this.

So, there are several ways to load your custom blocks, mainly:

  • add_action('enqueue_block_assets','xy_function') / add_action('enqueue_block_editor_assets','xy_function'), which at the moment is the default when creating a block with "create_guten_block". This is what I was using. It might change, see https://github.com/ahmadawais/create-guten-block/issues/21
  • register_block_type as per the handbook, see https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type/#enqueuing-block-scripts

While registering the block in PHP (like described in the handbook) is the default method and future proof, the enqueue_block_assets variant can load multiple blocks without the need to split your blocks into seperate files and define them again in PHP. "create_guten_block" for example merges any number of blocks into three files by default (blocks.build.js, blocks.editor.build.css and block.style.build.css).

Both ways do not conditionally load styles (yet).

When using the create_guten_block method, enqueue_block_assets, and only having a single block defined (or set up to split the files per block), the conditional loading can be added using has_block:

    function my_awesome_blocks_cgb_block_assets() {
      if (is_singular()) {
        $id = get_the_ID();
        if (has_block('my-awesome/block-type', $id)) {
            wp_enqueue_style(
              'my-awesome_blocks-cgb-style-css',
              plugins_url( 'blocks/dist/blocks.style.build.css', __FILE__ ),
            );
        }
      }
    }
    add_action( 'enqueue_block_assets', 'my_awesome_blocks_cgb_block_assets' );

You can combine register and conditional loading by leaving out the style / script parts in the register and load the according fontend files with enqueue_block_assets as in the code above.

The future proof method will be using register_block_type, as the script and style fields of it will most likely be used if conditional loading is ever implemented natively (see comment here).