Dynamic gutenberg block with react instead of php

i’m building a wordpress theme based on the wordpress rest api, So everything on the frontend is built with react. But I want to build a gutenberg custom block that displays the most popular posts. is there a way to build the dynamic part ( save part ) with react instead of PHP. If no, how can i make the “Read More” link bahave as a React router Navlink instead of an HTML tag, so when the user clicks on it the browser doesn’t refresh and the new route is pushed the props history.
Thank you.

update : when we build a gutenberg block the “edit:(props)” functon is react based, but the save function returns static html or can be dynamic with the use of php. But i’m building my theme with react not php so the content is rendered with react, So how can manupilate the “save:(props)” function to read block attributes and make the block integrates with javascript, So I might use react routers instead of link tags that refreshs the browser…

<Link to={route}>link</link> instead of <a href="https://wordpress.stackexchange.com/questions/345372/hrefto">link</a>

1 Answer
1

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