0

I am trying to figure out how to only use css for the block/blocks actually used on the frontend. With my current setup everything is bundled into my build/frontend.css file and so just using one of multiple blocks loads all the css because it is all in the built frontend.css file. But if I for example only use a hero block, I only want the hero css to be loaded on the frontend, not the entire css file.

Here is a basic idea of my folder structure

build
  frontend.css
  frontend.js
src
  index.js
  frontend.css
  frontend.js
  hero
   -index.js
   -index.css
  callToAction
   -index.js
   -index.css
index.php

In my php file:

// only load the frontend css and js if there is a block using it
add_filter( 'should_load_separate_core_block_assets', '__return_true' );


add_action('init', 'custom_register_gutenberg_blocks');
function custom_register_gutenberg_blocks() {
    
    // register scripts - backend
    wp_register_script('custom-blocks-editor-scripts',
        plugins_url('build/index.js', __FILE__),
        array('wp-blocks', 'wp-i18n', 'wp-editor'),
        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js') // version
    );

    // register scripts - frontend
    wp_register_script('custom-blocks-frontend-scripts',
        plugins_url('build/frontend.js', __FILE__),
        array('wp-blocks', 'wp-i18n', 'wp-editor'),
    );

    // register styles - backend
    wp_register_style('custom-blocks-editor-style',
       plugins_url('build/index.css', __FILE__),
       array('wp-edit-blocks'),
    );

    // register styles - frontend
    wp_register_style('custom-blocks-frontend-styles', 
        plugins_url('build/frontend.css', __FILE__),
    );

   
    // Allow inlining small stylesheets on the frontend if possible.
    wp_style_add_data( 'custpm-blocks-frontend-styles', 'path', dirname( __FILE__ ) . '/frontend.css' );

   register_block_type('custom/hero', array(
        'editor_script' => 'custom-blocks-editor-scripts',
        'editor_style'  => 'custom-blocks-editor-style',
        'style' => 'custom-blocks-frontend-styles',
        'script' => 'custom-blocks-frontend-scripts',
        'render_callback' => 'custom_hero'
    ));
    
    function custom_hero($attributes) {
         ob_start(); ?>
           <div>
               Content output here
           </div>
        <?php return ob_get_clean();
    }
}

Then for example in my hero block I load the css file from the same folder

src/hero/index.js

import "./index.css";
import { registerBlockType } from "@wordpress/blocks";

registerBlockType("custom/hero", {
 // edit: (props) => {}
 // save: (props) => {}
});

So, the js files are loading the css just from their specific block folder but in the php I am calling the frontend.css file from the build folder.

1

To get separate files for each block you'll need to bring your own webpack config

One as simple as this should work:

const defaultConfig = require('@wordpress/scripts/config/webpack.config');

module.exports = {
    ...defaultConfig,
    entry: {
        'hero': './src/hero',
        'call-to-action': './src/callToAction',
    },
};

Ryan Welcher has an example repo and a video walk-through of its creation (that link is to the part about creating the custom webpack config).

UPDATE: It turns out it is possible to get separate bundles without a custom webpack config but (with v19.1.0 of @wordpress/scripts) it will only work if the entry points have different filenames. That is, it will fail to include a file if another has the same name. For instance, this would build but foo/index.js would be left out:

"build:custom": "wp-scripts build foo/index.js bar/index.js"

Whereas this would work as expected:

"build:custom": "wp-scripts build foo/foo.js bar/bar.js"
1
  • Thank you and sorry for the delayed response. I will give this a go! Nov 23 '21 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.