masonitedoors/react-app-loader

An mu-plugin that provides an API for loading React applications built with create-react-app into the front-end of WordPress.

Installs: 1 772

Dependents: 0

Suggesters: 0

Security: 0

Stars: 2

Watchers: 4

Forks: 2

Open Issues: 1

Type:wordpress-muplugin

1.5.0 2023-04-18 15:33 UTC

This package is auto-updated.

Last update: 2024-12-18 18:48:22 UTC


README

React App Loader on Packagist Build Status

An mu-plugin that provides an API for loading React applications built with create-react-app into the front-end of WordPress.

Requirements

  • PHP >= 7.1
  • WordPress >= 5.0
  • React application built using Create React App >= 3.2

Setup

Loader

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

React App

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
 */

PHP Interface

ReactAppLoader\API::register()

The register method has 4 required parameters and should be called within the plugins_loaded action.

Usage

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'
    );
});

URL Structure

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.

Flushing WordPress Rewrite Rules

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

Settings → Permalinks

Rewrite rules can also be flushed via WP-CLI.

wp rewrite flush

Trailing Slash

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).

Remote React App Support

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'
    );
});

Recommendations

Using Images Within Your React App

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.

Avoiding Conflicting Styles

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:

Edit this example on codesandbox

Common Issues

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:

  1. 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.

  2. 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.

  3. 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.

Credit

This plugin is based off the great work done by humanmade/react-wp-scripts.