You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让React开发的WordPress插件内容被Google识别?

解决React开发WordPress短代码插件的SEO抓取问题

针对你用React开发WordPress短代码插件、内容无法被Google抓取的问题,结合你使用wp-scripts的情况,提供以下几种实用方案:

方案一:服务端渲染(SSR)适配WordPress

核心思路是在PHP短代码执行时,先通过Node环境或PHP扩展渲染React组件为静态HTML输出,再加载客户端JS做交互激活(hydrate),确保源码可见且可被抓取。

步骤1:扩展wp-scripts配置支持SSR打包

在项目根目录创建webpack.config.js,添加SSR打包规则:

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

module.exports = [
  // 保留原客户端打包配置
  defaultConfig,
  // 添加SSR打包配置
  {
    ...defaultConfig,
    entry: {
      ssr: './src/ssr.js',
    },
    output: {
      ...defaultConfig.output,
      filename: '[name].js',
      libraryTarget: 'commonjs2',
    },
    target: 'node',
    externals: {
      react: 'commonjs react',
      'react-dom': 'commonjs react-dom',
    },
  },
];

步骤2:编写SSR渲染脚本

创建src/ssr.js,负责渲染组件为HTML字符串:

import React from 'react';
import { renderToString } from 'react-dom/server';
import MyPluginComponent from './components/MyPluginComponent';

// 接收外部传入的短代码参数,输出渲染后的HTML
module.exports = (props) => renderToString(<MyPluginComponent {...props} />);

步骤3:PHP短代码中调用SSR渲染

方式A:使用Node环境执行SSR脚本(需服务器允许exec)

function my_plugin_shortcode($atts) {
    // 处理短代码参数
    $props = json_encode(shortcode_atts([
        'post_id' => '',
        'limit' => 5,
    ], $atts));

    // 执行SSR脚本获取静态HTML
    $ssr_script_path = plugin_dir_path(__FILE__) . 'build/ssr.js';
    $html = exec('node -e "const render = require(\''.$ssr_script_path.'\'); console.log(render('.$props.'))"');

    // 加载客户端JS/CSS
    wp_enqueue_script(
        'my-plugin-script',
        plugin_dir_url(__FILE__) . 'build/index.js',
        [],
        filemtime(plugin_dir_path(__FILE__) . 'build/index.asset.php'),
        true
    );
    wp_enqueue_style(
        'my-plugin-style',
        plugin_dir_url(__FILE__) . 'build/index.css',
        [],
        filemtime(plugin_dir_path(__FILE__) . 'build/index.css')
    );

    // 传递参数到客户端用于hydrate
    wp_localize_script('my-plugin-script', 'myPluginProps', $atts);

    // 输出带根节点的静态HTML
    return '<div id="my-plugin-root">' . $html . '</div>';
}
add_shortcode('my_react_plugin', 'my_plugin_shortcode');

方式B:使用PHP V8JS扩展(更安全,无需exec)

如果服务器安装了V8JS扩展,可直接在PHP中执行SSR脚本:

use V8Js;

function my_plugin_render_ssr($props) {
    $v8 = new V8Js();
    $ssr_script = file_get_contents(plugin_dir_path(__FILE__) . 'build/ssr.js');
    $props_json = json_encode($props);

    // 执行SSR渲染
    return $v8->executeString('
        global.props = JSON.parse(\''.$props_json.'\');
        const render = require(\''.plugin_dir_path(__FILE__).'build/ssr.js\');
        render(global.props);
    ', 'ssr-render');
}

// 短代码函数中调用上述方法即可

步骤4:客户端代码改为hydrate激活

修改src/index.js,用hydrateRoot替代createRoot,复用服务器渲染的DOM:

import React from 'react';
import { hydrateRoot } from 'react-dom/client';
import MyPluginComponent from './components/MyPluginComponent';

const root = document.getElementById('my-plugin-root');
hydrateRoot(root, <MyPluginComponent {...window.myPluginProps} />);

方案二:静态预渲染(适合内容固定的组件)

如果你的React组件内容不随短代码参数变化,可预渲染静态HTML,直接在短代码中输出。

步骤1:配置react-snap预渲染

安装依赖:

npm install react-snap --save-dev

修改package.json的脚本:

"scripts": {
  "build": "wp-scripts build && npm run prerender",
  "prerender": "react-snap"
},
"reactSnap": {
  "source": "public",
  "target": "build/prerendered",
  "inlineCss": true
}

创建public/index.html作为预渲染模板:

<!DOCTYPE html>
<html>
<body>
  <div id="my-plugin-root"></div>
  <script src="../build/index.js"></script>
</body>
</html>

步骤2:PHP短代码中加载预渲染HTML

function my_plugin_shortcode($atts) {
    // 加载客户端JS/CSS
    wp_enqueue_script(
        'my-plugin-script',
        plugin_dir_url(__FILE__) . 'build/index.js',
        [],
        filemtime(plugin_dir_path(__FILE__) . 'build/index.asset.php'),
        true
    );
    wp_enqueue_style(
        'my-plugin-style',
        plugin_dir_url(__FILE__) . 'build/index.css',
        [],
        filemtime(plugin_dir_path(__FILE__) . 'build/index.css')
    );

    // 读取预渲染的HTML内容
    $prerendered_html = file_get_contents(plugin_dir_path(__FILE__) . 'build/prerendered/index.html');
    // 提取根节点内的内容
    preg_match('/<div id="my-plugin-root">(.*?)<\/div>/s', $prerendered_html, $matches);
    $static_html = $matches[1] ?? '';

    return '<div id="my-plugin-root">' . $static_html . '</div>';
}
add_shortcode('my_react_plugin', 'my_plugin_shortcode');

方案三:PHP静态输出+React交互(极简方案)

如果组件数据来自WordPress,可直接用PHP查询数据并输出静态HTML,React仅负责添加交互逻辑:

function my_plugin_shortcode($atts) {
    // PHP查询数据(比如自定义帖子类型)
    $posts = get_posts([
        'post_type' => 'custom_post',
        'posts_per_page' => $atts['limit'] ?? 5,
    ]);

    // 输出静态HTML
    $static_html = '<div id="my-plugin-root"><ul>';
    foreach ($posts as $post) {
        $static_html .= '<li class="post-item" data-id="'.$post->ID.'">'.$post->post_title.'</li>';
    }
    $static_html .= '</ul></div>';

    // 加载React交互脚本
    wp_enqueue_script(
        'my-plugin-script',
        plugin_dir_url(__FILE__) . 'build/index.js',
        [],
        filemtime(plugin_dir_path(__FILE__) . 'build/index.asset.php'),
        true
    );

    return $static_html;
}
add_shortcode('my_react_plugin', 'my_plugin_shortcode');

客户端React只需挂载到已有的DOM上,添加点击事件等交互:

import React from 'react';
import { hydrateRoot } from 'react-dom/client';

const MyPluginComponent = () => {
    const handleClick = (e) => {
        const postId = e.currentTarget.dataset.id;
        // 交互逻辑,比如弹窗显示内容
    };

    return (
        <ul>
            {Array.from(document.querySelectorAll('.post-item')).map(item => (
                <li key={item.dataset.id} onClick={handleClick}>{item.textContent}</li>
            ))}
        </ul>
    );
};

const root = document.getElementById('my-plugin-root');
hydrateRoot(root, <MyPluginComponent />);

内容的提问来源于stack exchange,提问作者Sau Thapa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:30:44