Posted on: July 17, 2025
Các nhà phát triển muốn tạo ra trải nghiệm phong phú và tương tác nhất có thể sử dụng JavaScript, được hỗ trợ bởi các framework như React. React là một thư viện JavaScript giúp tạo giao diện người dùng động và tương tác vượt trội so với trang web tĩnh thông thường. Được Facebook tạo ra, React được duy trì tốt để đảm bảo bảo mật, ổn định và dễ sử dụng với hệ sinh thái cộng đồng phong phú.
Bài hướng dẫn này sẽ hướng dẫn bạn cách nhúng một ứng dụng React vào trang WordPress bằng cách tạo một widget có thể sử dụng nhiều lần trên nhiều trang. Về phía máy chủ, widget này được hiện thực như một shortcode của WordPress, sử dụng cú pháp dấu ngoặc vuông để gọi hàm PHP và hiển thị HTML.
Kết thúc bài, bạn sẽ tạo shortcode, chèn nó vào trang trong WP Admin và xem widget React hoạt động.
Đăng nhập với tài khoản không phải root, bạn sẽ không có quyền truy cập sửa tập tin WordPress. Để khắc phục, chạy lệnh thay đổi quyền sở hữu toàn bộ thư mục WordPress cho user của bạn và nhóm www-data (nhóm Apache):
sudo chown -R sammy:www-data /var/www/wordpress
Kiểm tra kết quả bằng cách liệt kê chi tiết thư mục:
ls -la /var/www/wordpress
Nếu quyền sở hữu được cập nhật đúng, các thư mục và tập tin sẽ thuộc về user của bạn với nhóm www-data.
Tạo một thư mục cho plugin trong wp-content/plugins, ví dụ react-wordpress
:
mkdir /var/www/wordpress/wp-content/plugins/react-wordpress
cd /var/www/wordpress/wp-content/plugins/react-wordpress
Tạo tập tin chính cho plugin:
nano react-wordpress.php
Thêm đoạn mã:
<?php
/**
* @wordpress-plugin
* Plugin Name: Embedding React In Wordpress
*/
defined('ABSPATH') or die('Direct script access disallowed.');
Kích hoạt plugin trong trang quản trị WordPress ở mục Plugins.
Tiếp theo, xác định các hằng số cho đường dẫn plugin:
define('ERW_WIDGET_PATH', plugin_dir_path(__FILE__) . '/widget');
define('ERW_ASSET_MANIFEST', ERW_WIDGET_PATH . '/build/asset-manifest.json');
define('ERW_INCLUDES', plugin_dir_path(__FILE__) . '/includes');
Tạo thư mục includes trong plugin để chứa các file PHP phụ trợ:
mkdir includes
Cài đặt Create React App phiên bản 3.0.1:
sudo npm install --global [email protected]
Khởi tạo ứng dụng React tên widget
trong thư mục plugin:
sudo create-react-app widget
Sau khi tạo, chuyển đến thư mục widget và chạy:
cd widget
sudo npm run build
Sửa file src/index.js
để React chỉ render nếu phần tử có id erw-root
tồn tại:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
const target = document.getElementById('erw-root');
if (target) { ReactDOM.render(<App />, target); }
serviceWorker.unregister();
Di chuyển ra thư mục plugin, tạo file includes/enqueue.php
:
<?php
// This file enqueues scripts and styles
defined('ABSPATH') or die('Direct script access disallowed.');
add_action('init', function() {
add_filter('script_loader_tag', function($tag, $handle) {
if (!preg_match('/^erw-/', $handle)) { return $tag; }
return str_replace(' src', ' async defer src', $tag);
}, 10, 2);
add_action('wp_enqueue_scripts', function() {
// Code enqueue sẽ được thêm ở bước 5
});
});
Cập nhật file chính plugin react-wordpress.php
để require file này:
require_once(ERW_INCLUDES . '/enqueue.php');
Đọc nội dung file asset-manifest.json
trong thư mục build để xác định các file CSS và JS cần load:
Trong includes/enqueue.php
, thêm đoạn mã:
add_action('wp_enqueue_scripts', function() {
$asset_manifest = json_decode(file_get_contents(ERW_ASSET_MANIFEST), true)['files'];
if (isset($asset_manifest['main.css'])) {
wp_enqueue_style('erw', get_site_url() . $asset_manifest['main.css']);
}
wp_enqueue_script('erw-runtime', get_site_url() . $asset_manifest['runtime~main.js'], array(), null, true);
wp_enqueue_script('erw-main', get_site_url() . $asset_manifest['main.js'], array('erw-runtime'), null, true);
foreach ($asset_manifest as $key => $value) {
if (preg_match('@static/js/(.*)\.chunk\.js@', $key, $matches)) {
if ($matches && is_array($matches) && count($matches) === 2) {
$name = "erw-" . preg_replace('/[^A-Za-z0-9_]/', '-', $matches[1]);
wp_enqueue_script($name, get_site_url() . $value, array('erw-main'), null, true);
}
}
if (preg_match('@static/css/(.*)\.chunk\.css@', $key, $matches)) {
if ($matches && is_array($matches) && count($matches) == 2) {
$name = "erw-" . preg_replace('/[^A-Za-z0-9_]/', '-', $matches[1]);
wp_enqueue_style($name, get_site_url() . $value, array('erw'), null);
}
}
}
});
Điều này đảm bảo các tập tin được tải đúng và tối ưu bằng cách thêm thuộc tính async defer
lên các thẻ <script>
.
Chỉnh sửa file package.json
của ứng dụng React, thêm trường homepage
:
{
"homepage": "/wp-content/plugins/react-wordpress/widget/build",
...
}
Chạy lại npm run build
trong thư mục widget để cập nhật đường dẫn build.
Thêm luật rewrite trong .htaccess
của WordPress tại thư mục /var/www/wordpress
:
<IfModule mod_rewrite.c>
RewriteRule ^wp-content/plugins/react-wordpress/widget/(build|public)/(.*) - [L]
RewriteRule ^wp-content/plugins/react-wordpress/widget/* totally-bogus-erw.php [L]
</IfModule>
Luật này cho phép truy cập hợp lệ đến thư mục build và public, còn lại trả về trang lỗi 404 để bảo vệ mã nguồn React.
Tạo file includes/shortcode.php
và require trong plugin chính:
require_once(ERW_INCLUDES . '/shortcode.php');
Nội dung shortcode.php
:
<?php
// This file enqueues your shortcode.
defined('ABSPATH') or die('Direct script access disallowed.');
add_shortcode('erw_widget', function($atts) {
$default_atts = array('color' => 'black');
$args = shortcode_atts($default_atts, $atts);
$uniqid = uniqid('id');
global $current_user;
$display_name = $current_user ? $current_user->display_name : 'World';
ob_start(); ?>
<script>
window.erwSettings = window.erwSettings || {};
window.erwSettings["<?= $uniqid ?>"] = {
'color': '<?= $args["color"] ?>',
'name': '<?= $display_name ?>',
};
</script>
<div class="erw-root" data-id="<?= $uniqid ?>"></div>
<?php
return ob_get_clean();
});
Sử dụng shortcode [erw_widget color="#cf6f1a"]
để chèn widget trong trang WordPress.
Trong React, chỉnh sửa index.js
:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
const App = ({ settings }) => (
<div className="App" style={{borderColor: settings.color}}>
<span className="App__Message">Hello,<br />{settings.name}!</span>
</div>
);
const targets = document.querySelectorAll('.erw-root');
Array.prototype.forEach.call(targets, target => {
const id = target.dataset.id;
const settings = window.erwSettings[id];
ReactDOM.render(<App settings={settings} />, target);
});
serviceWorker.unregister();
Chạy lại npm run build
để compile các thay đổi.
Qua bài hướng dẫn, bạn đã tạo thành công một plugin WordPress chứa ứng dụng React. Bạn đã xây dựng shortcode như một cầu nối để nhúng ứng dụng trong trang quản trị WP Admin, và đã tuỳ chỉnh widget với các tham số được cung cấp từ phía server.
Cơ sở này giúp bạn tự tin mở rộng ứng dụng React, tập trung vào trải nghiệm phía client, đồng thời dễ dàng thêm các công cụ kỹ thuật dành cho môi trường sản xuất tương thích với mọi cài đặt WordPress.
Tham khảo thêm các bài học nâng cao về React và TypeScript hoặc tích hợp dữ liệu API vào React để phát triển thêm.