Create a React WordPress theme using babel and webpack

Part 1 in a series on Creating a React WordPress theme, how to build and run React inside a WordPress theme using Babel and Webpack.

This post is part of the React WordPress Theme Collection

An Step-by-step guide on creating a React WordPress theme, to list WordPress Rest API posts and pages, display and create comments, integrate Server Side rendering using PHP.

  1. Create a React WordPress theme using babel and webpack
  2. Step-by-step Guide to displaying WordPress Rest API posts in a React WordPress theme
  3. Guide to Creating React WordPress menus in a WordPress Theme

In this development series we will be looking into building a React WordPress theme using PHP, and React Javascript library. Unlike most React Websites that are powered by a Headless WordPress Setup using the WordPress Rest API, we will be creating an installable theme allows us to take advantage of core wordpress features and plugins, along with other extras such as data preloading to remove initial Rest API request, server side rendering in php using spatie/server-side-rendering.

This article assumes that you have a local wordpress development environment setup along with npm or yarn package manager installed.

Creating a basic WordPress theme.

Start this React WordPress journey by creating a new theme, we do this adding a new folder within the themes directory called /wp-content/themes/jclabs-react-theme/, with the theme folder created there are a few required files before WordPress will allow us it to be activated. I have gone through each file and explained what it does.

/jclabs-react-theme/
|----/src/
|    |- App.js
|    |- index.js
|- style.css
|- index.php
|- webpack.config.js
|- .babelrc
|- package.json
|- functions.php

WordPress theme stylesheet – style.css

Style.css is required when creating a custom WordPress theme, we will only be using it to declare the theme name and version, our style.css file will not contain any css as these will be compiled from sass files during the webpack build process.

/*
Theme Name: JCLABS React Theme
Text Domain: jclabs-react-theme
Version: 1.0.0
Requires at least: 4.7
*/

WordPress theme entry point – index.php

index.php is the only WordPress theme template file that we will be using in our custom React WordPress theme, it is the main entry point for the React application which will replace the div element with the id of root. The wp_head and wp_footer functions are used by WordPress to output javascript and css files, along with other meta data that wordpress or installed plugins require.

<!DOCTYPE html>
<html lang="<?php language_attributes(); ?>">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title><?php wp_title(); ?></title>
    <?php wp_head(); ?>
</head>

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <?php wp_footer(); ?>
</body>

</html>

WordPress themes functions – functions.php

The functions.php is automatically loaded when the theme is active, this will hold all our custom functions that we will be using later when we start displaying WordPress posts and pages, but at the moment it will only be used to enqueue css and javascript files that will be generated by webpack when we build the React WordPress theme.

function jcrt_enqueue_scripts()
{

  $version = '1.0.0';
  if(defined('WP_DEBUG') && WP_DEBUG === true){
    $version = time();
  }

  wp_enqueue_script('theme', get_stylesheet_directory_uri() . '/dist/js/bundle.js', array('jquery'), $version, true);
  wp_enqueue_style('theme', get_stylesheet_directory_uri() . '/dist/css/style.bundle.css', array(), $version);

  $config = array(
    // TODO: Add any theme variables needed in react
  );
  wp_localize_script('theme', 'wp_config', $config);
}
add_action('wp_enqueue_scripts', 'jcrt_enqueue_scripts');

Main React Component – src/App.js

App.js is the main React component, this is a very basic component at the moment that renders a h1 tag with the words Hello World, this will expand upon this once we have a working WordPress React Theme.

import React, { Component } from 'react';

class App extends Component {
  render() {
    return <h1>Hello World</h1>;
  }
}

export default App;

React Render – src/index.js

index.js is the main javascript file that will render the React App component on the div element previously output in our WordPress React themes index.php file.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
  <BrowserRouter>
    <App/>
  </BrowserRouter>,
  document.getElementById('root')
);

Installing React and configuring Webpack

Babel Config – .babelrc

The babelrc config file loads the correct babel plugins to compile our react website making it compatiable with older browsers, converting modern javascript features into backwards compatiable code.

{
  "presets": ["@babel/env", "@babel/react"]
}

Javascript Dependencies – package.json

Within our package.json file we are loading react, react-dom and react-router-dom, along with all development dependencies to compile our application using webpack and babel.

There are two scripts that can be ran in the terminal via npm or yarn, which can be seen under the scripts node:

  • Start – development script that will compile the React WordPress theme and enable hot reloading using browser sync.
  • Build – compile React WordPress theme in production mode, this is used when using your theme in production mode.
{
  "name": "jclabs-react-theme",
  "version": "1.0.0",
  "private": true,
  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "^5.1.2"
  },
  "scripts": {
    "start": "node_modules/.bin/webpack --watch",
    "build": "node_modules/.bin/cross-env NODE_ENV=production node_modules/.bin/webpack"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/preset-env": "^7.9.0",
    "@babel/preset-react": "^7.9.4",
    "babel-loader": "^8.1.0",
    "browser-sync": "^2.26.7",
    "browser-sync-webpack-plugin": "^2.2.2",
    "cross-env": "^7.0.2",
    "css-loader": "^3.4.2",
    "file-loader": "^6.0.0",
    "mini-css-extract-plugin": "^0.9.0",
    "node-sass": "^4.13.1",
    "sass-loader": "^8.0.2",
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11"
  }
}

Webpack Config – webpack.config.js

Webpack.config.js is the main webpack configuration file for our React WordPress theme, it reads the index.js file and generates all output into the dist folder, building all sass into css, all javascript into a single file, and moves all images into an img folder.

Depending on the name you have used when creating your wordpress theme you will need to change line 33 replacing jclabs-react-theme with the name of your theme folder.

Depending if you are running in development or production mode browser sync has been setup to to live reload your theme and assets, if your webserver is not running under https://localhost you will need to change line 42 with your local development url.

const path = require('path');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const webpackConfig = {
  mode: 'development',
  entry: {
    bundle: path.join(__dirname, 'src', 'index.js')
  },
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /.(css|scss)$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'wp-content/themes/jclabs-react-theme/dist/img/[name].[ext]'
          }
        }
      }
    ]
  },
  plugins: [
    new BrowserSyncPlugin({
      proxy: {
        target: 'https://localhost'
      },
      files: ['**/*.php'],
      cors: true,
      reloadDelay: 0,
      open: false
    }),
    new MiniCssExtractPlugin({
      disable: false,
      filename: 'css/style.[name].css',
      allChunks: true
    })
  ]
};

if (process.env.NODE_ENV === 'production') {
  webpackConfig.mode = 'production';
}

module.exports = webpackConfig;

Installing the WordPress Theme

With all the React WordPress theme files created, it is time to see those words every developer likes to see Hello World. But first we need to Install and build the javascript files.

Building react wordpress theme

We need to install all javascript dependencies that have been declared in the package.json file, the command is slightly different depending if you are running NPM or Yarn, open your theme folder.

cd /var/www/html/wp-content/themes/jclabs-react-theme/

Once in the theme folder install javascript dependencies and start compile the react application, in your terminal run the relevent code.

# Run using Yarn
yarn
yarn start

# Run using Npm
npm install
npm run start

Installing and Viewing the WordPress React theme

With the javascript files compiled successfuly, if you have not already activate the WordPress theme via Appearance > Themes > JCLABS React Theme, do so now.

When you view your website you should see the words Hello World , this will look very basic right now, but now that we have react application being rendered in the WordPress theme we can now focus on the juicy parts which will be looking at in the future, such as integrating with the WordPress rest api, Server side rendering using PHP.

Leave a Reply

Fields marked with an * are required to post a comment