Add React To WordPress Admin

Add React To WordPress Admin

Welcome

In this post we will go over how to set up your plugin to use React within its admin page.

Dev Environment

You could use creat-react-app inside a sub folder of your plugin but, in my opinion, it creates to many things that are not needed. So we won't be using that for this application.

I'll be starting with my default multi-block plugin template. You can check out my previous post on how to fully set that up @ this link. Through that setup I already have npm and webpack set up for registering multiple block-types. My directory structure looks like this after I have added a place for my admin pages.

First we will install react and react dom as dependencies.

npm install react react-dom 

Then we need to install our dev dependencies (Babel compiler).

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader

You will need to add a .babelrc file to your plugin root directory with the following as the contents.

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

And last some helpers for webpack.

npm install --save-dev style-loader css-loader file-loader

Webpack

Next is configuring webpack in a way that will compile our React, while still doing what it needs to do for the WordPress blocks. We do this by giving module exports an array with two different config objects. This setup will also not do any code splitting making our lives a bit easier for this specific instance.

const defaultConfig = require('@wordpress/scripts/config/webpack.config');
const path = require("path");

module.exports = [
    {
    ...defaultConfig,
    entry: {
        'test-one': './includes/blocks/block-one/src',
    },
},
    {
        entry: "./includes/admin/pages/main/src/",
        output: {
            filename: "wp-multi-block-main.js",
            path: path.resolve(__dirname, "build"),
        },
        resolve: {
            modules: [__dirname, "src", "node_modules"],
            extensions: ["*", ".js", ".jsx", ".tsx", ".ts"],
        },
        module: {
            rules: [
                {
                    test: /\.jsx?$/,
                    exclude: /node_modules/,
                    loader: require.resolve("babel-loader"),
                },
                {
                    test: /\.css$/,
                    use: ["style-loader", "css-loader"],
                },
                {
                    test: /\.png|svg|jpg|gif$/,
                    use: ["file-loader"],
                },
            ],
        },
    }
];

The first object in module exports, as shown above, is for using the default wp configs with multiple blocks, The second object is what will compile our React code. Make sure your entry is pointing to the right directory and your output file makes sense for where it will be applied. If you are wanting to have multiple separate react pages then just add another config object to the array above with the entry and output changed appropriately.

Adding the admin page to WordPress

Let's add the admin page to WordPress inside our plugins main php file.

function menu_page() {
	add_menu_page(
		page_title: 'Multi Block',
		menu_title: 'Multi Block',
		capability: 'manage_options',
		menu_slug:  'multi-block',
		function: function () {
			include_once WP_MULTI_BLOCK_PLUGIN_DIR . 'includes/admin/pages/main/wp-multi-block.php';
		},
		icon_url:   'dashicons-schedule',
		position:   3
	);
}

add_action( 'admin_menu', 'menu_page');

Now lets make a php file that we specified above to properly render the menu page. Put some text in there of your choice, just to make sure it is showing the right page. Now you should see your admin page in the menu and when you click on it, you should see the text that you put in the pages php file.

Setting up the React files

In your pages src folder (wp-multi-block/includes.admin/pages/main/src), add and index.js file and an App.js file. This will be the root of all our React code.

index.js

import React from "react"
import ReactDom from "react-dom"
import App from "./App";

ReactDom.render(<App/>, document.querySelector("#wp-multi-block"))

App.js

import React from "react";

const App = () => (
    <div>
        <h1>Hello From React</h1>
    </div>
);

export default App

Now in your php file for the page, add a div with the selector you specified in your index.js file. Ok we are almost there, just need to properly enqueue the scripts so WordPress will load them on this admin page. Back in the plugins main php file lets make some changes to the function that adds the admin page.

function menu_page() {
	$hook_suffix = add_menu_page(
		page_title: 'Multi Block',
		menu_title: 'Multi Block',
		capability: 'manage_options',
		menu_slug:  'multi-block',
		function: function () {
			include_once WP_MULTI_BLOCK_PLUGIN_DIR . 'includes/admin/pages/main/wp-multi-block.php';
		},
		icon_url:   'dashicons-schedule',
		position:   3
	);

	function script_enqueue() {
		wp_enqueue_script(
			handle: 'wp-multi-block-js',
			src:                   WP_MULTI_BLOCK_PLUGIN_URL . 'build/wp-multi-block-main.js',
			deps:                  [],
			ver:                   1,
			in_footer:             true
		);
	}

	add_action( 'admin_print_scripts-' . $hook_suffix, 'script_enqueue');
}

add_action( 'admin_menu', 'menu_page');

Here we are using the return value of the add_menu_page() to get the page suffix. Then we add an action admin_print_scripts- with the $hook_suffix that calls a function that enqueues the compiled script at the proper url address.

Now run npm start, navigate to your custom admin menu page, and you should see your React code there.