Pre-requisites:
- WordPress development environment, for example local WordPress development using Docker
- Existing React Web / Ant Design Pro project
Register Shortcode in WordPress
Create the WordPress plugin folder, e.g. in folder wp-content/plugins
, create folder embed-react
.
Create the plugin file embed-react.php
with skeleton as follows:
<?php
/*
Plugin Name: Embed React
Plugin URI: https://soluvas.com/
Description: Embed React
Author: Hendy Irawan
Version: 1.0.0
Author URI: https://soluvas.com/
*/
class EmbedReact_Plugin {
public static $instance;
public static function get_instance() {
if (!self::$instance) {
self::$instance = new EmbedReact_Plugin();
}
return self::$instance;
}
public function __construct() {
add_shortcode( 'embed_react', [$this, 'handle_shortcode'] );
}
public function handle_shortcode($atts) {
return <<<HERE
Let's embed... yay...!
HERE;
}
}
EmbedReact_Plugin::get_instance();
Activate that plugin, then let’s test it.
In WordPress dashboard, create a new Page with slug “chat
“.
Add a new Shortcode block, put: [embed_react]
Go to http://your_site/chat/ and ensure you can see your plugin’s shortcode working.
Embed Ant Design Pro App
In the Ant Design Pro project, create a new config/config.wordpress.ts
file:
// https://umijs.org/config/
import { defineConfig } from 'umi';
export default defineConfig({
base: '/chat/',
publicPath: '/wp-content/plugins/embed-react/dist/',
});
Explanation:
- base: this must match your WordPress frontend page’s permalink URL
- publicPath: this must match your WordPress plugin’s path
Build your Ant Design Pro app using the UMI_ENV=wordpress
:
UMI_ENV=wordpress yarn build
Copy the generated dist/
folder into your WordPress project under plugins/embed-react/
.
Edit the plugin’s handle_shortcode() function to include the React root element and CSS/script calls:
public function handle_shortcode($atts) {
$umi_dist = plugins_url('dist', __FILE__);
return <<<HERE
<link rel="stylesheet" href="$umi_dist/umi.143062e9.css" />
<script>
window.routerBase = "/chat/";
</script>
<script>
//! umi version: 3.3.9
</script>
<div id="root">
<style>
html,
body,
#root {
/* height: 100%; */
margin: 0;
padding: 0;
}
#root {
background-image: url("$umi_dist/home_bg.png");
background-repeat: no-repeat;
background-size: 100% auto;
}
.page-loading-warp {
display: flex;
align-items: center;
justify-content: center;
padding: 98px;
}
.ant-spin {
position: absolute;
display: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
color: rgba(0, 0, 0, 0.65);
color: #1890ff;
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
text-align: center;
list-style: none;
opacity: 0;
-webkit-transition: -webkit-transform 0.3s
cubic-bezier(0.78, 0.14, 0.15, 0.86);
transition: -webkit-transform 0.3s
cubic-bezier(0.78, 0.14, 0.15, 0.86);
transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86),
-webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
-webkit-font-feature-settings: "tnum";
font-feature-settings: "tnum";
}
.ant-spin-spinning {
position: static;
display: inline-block;
opacity: 1;
}
.ant-spin-dot {
position: relative;
display: inline-block;
width: 20px;
height: 20px;
font-size: 20px;
}
.ant-spin-dot-item {
position: absolute;
display: block;
width: 9px;
height: 9px;
background-color: #1890ff;
border-radius: 100%;
-webkit-transform: scale(0.75);
-ms-transform: scale(0.75);
transform: scale(0.75);
-webkit-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
opacity: 0.3;
-webkit-animation: antspinmove 1s infinite linear alternate;
animation: antSpinMove 1s infinite linear alternate;
}
.ant-spin-dot-item:nth-child(1) {
top: 0;
left: 0;
}
.ant-spin-dot-item:nth-child(2) {
top: 0;
right: 0;
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.ant-spin-dot-item:nth-child(3) {
right: 0;
bottom: 0;
-webkit-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.ant-spin-dot-item:nth-child(4) {
bottom: 0;
left: 0;
-webkit-animation-delay: 1.2s;
animation-delay: 1.2s;
}
.ant-spin-dot-spin {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-animation: antrotate 1.2s infinite linear;
animation: antRotate 1.2s infinite linear;
}
.ant-spin-lg .ant-spin-dot {
width: 32px;
height: 32px;
font-size: 32px;
}
.ant-spin-lg .ant-spin-dot i {
width: 14px;
height: 14px;
}
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
.ant-spin-blur {
background: #fff;
opacity: 0.5;
}
}
@-webkit-keyframes antSpinMove {
to {
opacity: 1;
}
}
@keyframes antSpinMove {
to {
opacity: 1;
}
}
@-webkit-keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
@keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
</style>
<div
style="
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
min-height: 420px;
"
>
<img src="$umi_dist/pro_icon.svg" alt="logo" width="256" />
<div class="page-loading-warp">
<div class="ant-spin ant-spin-lg ant-spin-spinning">
<span class="ant-spin-dot ant-spin-dot-spin"
><i class="ant-spin-dot-item"></i><i class="ant-spin-dot-item"></i
><i class="ant-spin-dot-item"></i><i class="ant-spin-dot-item"></i
></span>
</div>
</div>
<div
style="display: flex; align-items: center; justify-content: center"
>
<img
src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg"
width="32"
style="margin-right: 8px"
/>
Ant Design
</div>
</div>
</div>
<script src="$umi_dist/umi.97a47641.js"></script>
HERE;
}
Check your WordPress page: