8

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="hrefto">link</a>
1
  • What exactly have you tried? What specific problem are you having? Please edit your question to provide additional detail, especially samples of your code.
    – Pat J
    Commented Aug 18, 2019 at 22:28

1 Answer 1

10

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.

3
  • 1
    Thanks! If registering block from block.json metadata, adding "script": "file:./build/client.js" seems to work as well, without editing the php-file.
    – nomadoda
    Commented May 23, 2021 at 19:09
  • dear please can you share some examples, I am trying to work with the latest_post dynamics block, and I tried to use react at the frontEnd side but still didn't found a good solution. thanks Commented Sep 7, 2021 at 9:09
  • @IrfanAhmed do not post comments as the solution to the question. I've turned it into a comment, but I don't know what it has to do with this question
    – Tom J Nowell
    Commented Sep 7, 2021 at 9:43

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.