Dynamic gutenberg block with react instead of php

Gutenberg is not intended to do dynamic React stuff in front-end.

Nevertheless there is a way to bypass this problem:

I assume the structure of gutenberg block when using npm init @wordpress/block my-block to init your block.

You have to register your own client-side script in my-block.php to be executed on front-end; one drawback: it is loaded on every page.

function create_block_my_block_init()
{
    $client_js="build/client.js";
    wp_register_script(
        'create-block-my-block-client',
        plugins_url($client_js, __FILE__),
        $script_asset['dependencies'],
        $script_asset['version']
    );

    $client_css="build/client.css";
    wp_register_style(
        'create-block-my-block-client',
        plugins_url($client_css, __FILE__),
        array(),
        filemtime("$dir/$client_css")
    );

    ...

    register_block_type('create-block/my-block', array(
        ...
        'script' => 'create-block-my-block-client',
        'style'  => 'create-block-my-block-client', // Override default and import custom scss file.
    ));
}

Note that you can’t use build/style-index.css / style.scss anymore or use register_block_style for that purpose. But better import your custom style via import './custom.scss'; in your React component (here: MyComponent).

Add webpack.config.js to your root folder in order to load your script:

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

module.exports = {
    ...defaultConfig,
    entry: {
        ...defaultConfig.entry,
        client: './src/client.js',
    },
};

Add a HTML wrapper for your front-end in the src/save.js so you can reference your script:

export default function save() { return (
    <div className="my-block-wrapper"></div>
);}

Note that you shouldn’t add the wrapper to the src/edit.js as the React components are loaded dynamically, so use directly your custom components there.

import MyComponent from '@path_to_node_modules/MyComponent';

export default function Edit( { className } ) { return (
     <MyComponent/>
);}

Add your front-end react code to src/client.js:

import { render } from '@wordpress/element';
import MyComponent from '@path_to_node_modules/MyComponent';

window.addEventListener('DOMContentLoaded', (event) => {
    const wrappers = document.getElementsByClassName(`my-block-wrapper`);
    for(let wrapper of wrappers) {
        render(<MyComponent/>, wrapper);
    }
});

See my full example here.

Source 1: https://javascriptforwp.com/adding-react-to-a-wordpress-theme-tutorial/

Source 2: https://stackoverflow.com/questions/51771125/wordpress-gutenberg-react-components-on-front-end

Source 3: https://www.youtube.com/watch?v=jauZCeLrGFA

If you have feedback or improvements feel free to edit.

Leave a Comment