This is a walkthrough of how to set up for building a React app and using SASS in a WordPress environment.

Prerequisites/Assumptions:

  • you have a WP site set up already
  • you have a custom theme set up already. You could adapt these instructions to use within a custom plugin easily too.
  • you’re working in a mac or linux OS. You’d probably have to adapt these instructions a bit on a Windows OS.

Install Node.js

Check if you already have node installed

node --version

If you don’t have node installed, please find some instructions on how to install node on your system, and come back. This should also install npm (Node Package Manager) which you can confirm with:

npm --version

You’ll use npm to install various packages/dependencies like React itself.

Set up React

In your terminal navigate to the root of your custom theme directory (e.g.: wp-content/themes/my-theme/)

Use the npx command to create a base React app in a subdirectory:

npx create-react-app my-react-app

Now, you’ll see a new folder in your theme called my-react-app

Open up my-react-app/src/App.js and edit it to look like this:

import { createRoot } from 'react-dom/client'

const container = document.querySelector('#root')
const root = createRoot(container)
root.render(<App/>)

export default function App() {
  return <div>Moo!</div>
}

Next, use npm to build the app. Go into the my-react-app dir and

npm run build

This command triggers the build script to run. The build script is defined in the package.json file that you’ll see in the my-react-app folder.

When you run that command it transpiles the React code (jsx) into normal js that browsers can interpret. The resulting js will show up in the my-react-app/build/static/js/main.[some hash].js file. You’ll never want to directly edit this file directly, this is just the output of what the build process does for you based on the code you write in the my-react-app/src/ folder.

Now we need to create a container in our WP site for this app to show up in!

Create the target element in WordPress

The simplest way to add the target element is to modify one of your WordPress theme’s template files where you want the React app to appear. This could be a specific page template, or a custom template part, depending on where you want the React app to load.

For this example we’ll make a new PHP file for your custom page template. For example, you could name it page-react-app.php:

<?php
/*
Template Name: React App Page
*/

get_header();

?>

<div id="primary" class="content-area">
  <main id="main" class="site-main">
    <?php
    while ( have_posts() ) :
      the_post();
      ?>
      <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
          <div id="root"></div> <!-- React app will attach here -->
      </article>
    <?php endwhile; ?>
  </main>
</div>

<?php get_footer(); ?>

Create a new page in WordPress and assign it the “React App Page” template from the Page Attributes section in the editor. Publish or update the page. You’ve now created a page that will house the React app that we are creating.

Connect React with Wordpress

Next you’ll need to tell WP how to include the built/transpiled React scripts that have been created by the previous build step.

Finally, enqueue the React app’s main js and css file in your theme’s functions.php (or wherever else makes sense for your project). This function scans the build dir for the latest hashed entry js and css and enqueues them:

function mytheme_enqueue_react_app() {
  $react_app_dir = get_template_directory() . '/my-react-app/build/static/';
  $react_app_url = get_template_directory_uri() . '/my-react-app/build/static/';
  $react_app_css_dir = $react_app_dir . 'css/';
  $react_app_js_dir = $react_app_dir . 'js/';

  $css_files = scandir($react_app_css_dir);
  $js_files = scandir($react_app_js_dir);

  if ($css_files) {
    $main_css_file = preg_grep('/^main\..*\.css$/', $css_files);
    if (!empty($main_css_file)) {
      $main_css_file = reset($main_css_file); // Get the first match
      error_log(print_r($main_css_file, true));
      wp_enqueue_style('my-react-app-style', $react_app_url . 'css/' . $main_css_file);
    }
  }

  if ($js_files) {
    $main_js_file = preg_grep('/^main\..*\.js$/', $js_files);
    if (!empty($main_js_file)) {
      $main_js_file = reset($main_js_file);
      wp_enqueue_script('my-react-app-script', $react_app_url . 'js/' . $main_js_file, [], null, true);
    }
  }
}
add_action('wp_enqueue_scripts', 'mytheme_enqueue_react_app');

Test it out

This is our Hello World moment. However at Entra we prefer to Moo!

Visit the page that you set up previously. The Moo! coming from the React app should show up on the page. The React app is rendering within the div with the id root.

Set up SASS

Install the SASS preprocessor:

npm install sass

When you created the app in the earlier step using npx create-react-app my-react-app Create React App (CRA) already set everything up to be able to preprocess sass.

You can write an style.scss file in the same folder as your App.jsx:


$bg: #ccc;

.app {
  background-color: $bg
}

And then update your App.jsx:

import { createRoot } from 'react-dom/client'
import './style.scss'

const container = document.querySelector('#root')
const root = createRoot(container)
root.render(<App/>)

export default function App() {
  return <div className="app">Moo!</div>
}

Now run npm run build again, refresh your page, and you should see the update!

Development workflow

It’s tiring having to run npm run build everytime you make a change in your code, so let’s set up a workflow that automatically watches and rebuilds the app every time you make a change.

On the command line, install the chokidar package, just for the dev environment:

npm install --save-dev chokidar-cli

Chokidar is a library that provides for watch files and directories for changes, and we use it to monitor our src directory for changes, and to trigger the build process automatically when it does detect them.

Modify the scripts section of your package.json file:

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject",
  "watch": "chokidar 'src/**/*' -c 'npm run build'"
},

Run this new watch script that you just added using npm:

npm run watch

Now, whenever you change and save a file in your app, it will get built/transpiled to that /react-app/build/static/js/ folder. After you make a change, you should be able to just reload the page and the updates should show up.

Next steps

This setup gives you the basic ssetup to get started playing with React using SASS in a Wordpress context.

One shortcoming of this setup is that when you save a file, the chokidar package obeserves the change and then triggers the full production-optimized build. This is a bit of a slow build process, and in practice on dev we can do better with a build process that’s optimized for quick turnaround, rather than the efficient filesize etc that we want for production.

Another nice-to-have would be hot reloading. This makes it so that when you make a change in your code, it updates automatically to your browser without having to reload the page. This can really boost your productivity in development, and its a lot more fun to work with as well.

Both of these improvements can be handled by taking a slightly more invovled hand, working with Webpack directly, rather than indirectly via create-react-app.

If I find the time and inspiration, I’ll cover this in another blog post!