An mu-plugin that provides an API for loading React applications built with create-react-app into the front-end of WordPress.
- PHP >= 7.1
- WordPress >= 5.0
- React application built using Create React App >= 3.2
Add the plugin to your site's mu-plugins directory.
This plugin is also available to install via composer.
composer require masonitedoors/react-app-loader
While this loader does not require any specific structure to your React application, it does require the React app to be loaded as a WordPress plugin. In order to do this, we will need to add a single PHP file so WordPress can recognize it as a WordPress plugin. Although the PHP file can be named anything, the filename should match the nomenclature of the React app directory name in order to follow WordPress plugin development best practices.
/react-app-name
/public
/src
package.json
package-lock.json
README.md
react-app-name.php
yarn.lock
This PHP file (e.g. react-app-name.php
) should include header comment what tells WordPress that a file is a plugin and provides information about the plugin.
Example:
<?php
/**
* Plugin Name: My React App
* Description: A brief description of what this plugins does.
* Version: 1.0.0
* Author: Masonite
* Author URI: https://www.masonite.com/
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/
The register
method has 4 required parameters and should be called within the plugins_loaded
action.
Parameter | Type | Description |
---|---|---|
$slug | string | The page slug where the React app will live on the site. The loader will also reserve this slug with WordPress, preventing any new posts from being made at the same URL. If any existing posts share the defined slug, they will not be able to be accessed on the front-end of the site once rewrite rules are flushed. |
$root_id | string | The id of the root element that the React app should mount to. By default, Create React App has this as 'root' . |
$cra_directory | string | The absolute path to the plugin directory that contains the react app. In most situations, this should be plugin_dir_path( __FILE__ ) . This can also be a URL to the base directory of a React app on a different website. |
$role | string | The WordPress user role required to view the page. If a user tries to access the page without this role, they will be redirected to the site's home_url(). If no authentication is needed, this should be set as 'nopriv' . |
$callback | callable | Optional callback function. This is only fired on the registered page before the React app assets are enqueued. |
$wp_permalinks | array | Optional array of subdirectories off of the defined slug that we DO WANT WordPress to handle. |
With the loader installed as an mu-plugin, we can utilize the ReactAppLoader\API::register()
method to register our React app WordPress plugin with the loader.
add_action( 'plugins_loaded', function() {
\ReactAppLoader\API::register(
'my-react-app-slug',
'root',
plugin_dir_path( __FILE__ ),
'administrator'
);
});
When a React plugin is registered with this loader plugin, a virtual page is created within WordPress. As a result, this new page will not show up within the regular pages/posts list in wp-admin. Because of the nature of creating a virtual page by adding new rewrite rules to WordPress, the rewrite rules will need to be flushed before the new page will be accessible.
You'll need to refresh your site's rewrite rules in the database before you will see any React apps registered with the loader. This can be done by visiting your site's permalinks settings page in the admin area.
Visiting the Permalinks screen triggers a flush of rewrite rules
Rewrite rules can also be flushed via WP-CLI.
wp rewrite flush
Trailing slash has been removed for registerd React app pages. This was done in an effort to create consistency in behavior with create-react-app's node-server structure (the environment that fires up when you run npm start
).
Support for loading React apps hosted on other websites is available as of version 1.4.0.
This can be achived by using a URL to the root of the React app For the 3rd argument in the register method. If your React app's asset-manifest.json is https://example.org/my-react-app/asset-manifest.json, use the first part of the URL (omit asset-manifest.json).
add_action( 'plugins_loaded', function() {
\ReactAppLoader\API::register(
'my-react-app-slug',
'root',
'https://example.org/my-react-app/',
'nopriv'
);
});
It is up the React app to ensure that any images used are using absolute paths. It is recommended to use a digital asset management service such as Widen. Any images using relative paths within the React app will be broken when the app is loaded within WordPress.
When the React app is loaded from within WordPress, there is potential for styling conflicts introduced from theme/plugin CSS. It is recommended that you scope your React app's base styles within the React app at a root component using CSS Modules.
App.js:
import styles from "./App.module.scss";
function App() {
return <div className={styles.App}>...</div>;
}
App.module.scss:
// App root styles.
.App {
...
// Our apps base element styles. These will be globally scoped under App.
:global {
h1 {
...
}
p {
...
}
a {
...
}
em {
...
}
}
}
Once implemented, our base styles will now be scoped under the root hashed component:
I am getting a 404 when hitting the page slug I registered.
Verify that your React app WordPress plugin has been activated. Your site's rewrite rules might not have been flushed or flushed properly. See Flushing WordPress Rewrite Rules for instructions.
I am able to hit the page slug I registered, but my React app is not loading.
This could be happening from a few things:
-
If your React app is using react router, you may need to specify a basename. This should be the exact same value as the slug registerd with the loader. See Browser Router.
-
The loader relies on the newer asset-manifest.json structure that was introduced in create-react-app v3.2.0. If your React app was built using an eariler version of create-react-app, you will need to update your React app.
-
The asset-manfiest.json could not be found at all within your React app. Most likely your React app was never built or the build failed.
I am being redirected to my site's homepage when trying to access the page slug I registered.
This happens when your current WordPress user does not have the same role that was defined when registering with the loader.
This plugin is based off the great work done by humanmade/react-wp-scripts.