skip to content

Search

Part IV: React and Sage in Wordpress

3 min read

It's the future, and we ought to be able to use modern front-ends in WordPress. Good news. We can.

React in Wordpress without Headless

Don’t get me wrong, Headless Wordpress has a lot of neat advantages. But it’s also not entirely simple. There’s a lot of valid use cases where you want the best of both worlds: the ability to use react for some key components while also having the flexibility offered with blocks and ACF.

It’s not hard, conceptually. Basically, just…“make it work the same, but with react”. Easy, right?

We already use Vite with Sage

And you’re probably already using Tailwind, right?

Installing react is not alchemy at that point:

cd ./wp-content/theme-root
npm install react

You need to run this from your theme root, since it’s Sage that is using Vite. Since it’s already using Vite, it’s easy to bundle it.

plugins: [
    tailwindcss(),
    react(),
    //...
]

Just Make React Code, Now

Add your code to resources/js/components (or however you want to manage your crap). You can do all the normal react-y things. You can make providers that interact with the WP JSON API, you can nest other components, you can include other packages.

But you do need to do something special to hydrate your react component and actually render it. There’s always gotchas.

In app.jsx:

    import Marquee from "./component/Marquee"
    const registry = {
        'marquee': Marquee 
    }

    // inside a querySelectorAll foreach with (el) passed as the HTML element
    const Component = registry[componentName];
    const props = JSON.parse(el.dataset.props)
    const root = createRoot(el);
    root.render(<Component {...props}/>);

And now you’ve just manually hydrated the react component with properties serailzed into JSON from WordPress.

Yes, I’ve skipped over a few small details. You need to decide exactly how to implement this registry.

Server fallbacks, Next.js bridge

There’s a few things we could improve.

First, when we hydrate a placeholder div, that’s fine for search engines like Google that use headless versions of browsers to crawl sites. They will indeed see your react code and interact with it. But it gives little benefit for more primitivate crawlers.

This is easy to fix by providing SEO/rendering fallback code inside the div that’s going to be hydrated by react. All this markup will be destroyed as react bootstraps, but it offers a SSR solution without a full SSR solution (WP handles it).

An even more comprehensive workflow would be to obtain this fallback automatically using a NextJS bridge. I might add a series on this, later.

Making this Work in the Admin

I’ve also skipped over some details abot how this will all work inside the WordPress admin, which has its own layer of react that gleefully loves to get in the way. Also, if you change a property in the block editor, the component must know to remount based on that event.

If you really don’t want to work for the answers…well, just hire me, please!