基于Headless CMS与Next.js:如何实现WordPress修改自动同步至Next.js站点
实现WordPress内容自动同步至Next.js站点的方案
以下是几种可靠的实现方案,覆盖从基础到进阶的场景:
方案1:WordPress REST API + Next.js 增量静态再生(ISR)
这是最轻量化的方案,利用Next.js的ISR特性实现内容增量更新,无需全量重建站点。
步骤1:Next.js 配置内容获取与ISR
在Next.js的动态页面(如pages/posts/[slug].js)中,通过REST API拉取WordPress内容,并启用ISR:
export async function getStaticProps({ params }) { // 从WordPress REST API获取单篇文章 const res = await fetch(`https://your-wp-site.com/wp-json/wp/v2/posts?slug=${params.slug}`); const post = await res.json(); if (!post.length) { return { notFound: true }; } return { props: { post: post[0] }, revalidate: 60, // 每60秒自动验证内容是否更新 }; } export async function getStaticPaths() { // 预生成已发布的文章路径 const res = await fetch(`https://your-wp-site.com/wp-json/wp/v2/posts`); const posts = await res.json(); const paths = posts.map(post => ({ params: { slug: post.slug }, })); return { paths, fallback: 'blocking' }; // 未预生成的路径请求时动态生成 }
步骤2:配置WordPress Webhook触发更新
在WordPress的functions.php中添加钩子,当内容发布/更新时,调用Next.js的API路由触发页面重新生成:
add_action('save_post', 'trigger_nextjs_revalidate', 10, 3); function trigger_nextjs_revalidate($post_id, $post, $update) { // 跳过自动保存和修订版本 if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) return; // 只处理已发布的内容 if ($post->post_status !== 'publish') return; $secret = 'your-secure-key'; // 与Next.js环境变量一致 $nextjs_api_url = "https://your-nextjs-site.com/api/revalidate?secret={$secret}"; wp_remote_post($nextjs_api_url, [ 'headers' => ['Content-Type' => 'application/json'], 'body' => json_encode(['slug' => $post->post_name]), 'timeout' => 10, ]); }
步骤3:Next.js 实现Webhook处理路由
创建pages/api/revalidate.js,接收WordPress的请求并触发页面再生:
export default async function handler(req, res) { // 验证请求合法性 if (req.query.secret !== process.env.REVALIDATE_SECRET) { return res.status(401).json({ message: 'Invalid secret' }); } try { const { slug } = req.body; await res.revalidate(`/posts/${slug}`); return res.json({ revalidated: true }); } catch (err) { return res.status(500).send('Error revalidating'); } }
方案2:WordPress Action Scheduler + Next.js API(异步触发)
如果担心Webhook阻塞WordPress内容保存流程,可以用WordPress的Action Scheduler插件实现异步触发:
步骤1:安装并配置Action Scheduler
在WordPress后台安装Action Scheduler插件,然后修改functions.php:
add_action('save_post', 'schedule_nextjs_revalidate', 10, 3); function schedule_nextjs_revalidate($post_id, $post, $update) { if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) return; if ($post->post_status !== 'publish') return; // 调度异步任务 as_schedule_single_action( time(), 'execute_nextjs_revalidate', ['slug' => $post->post_name] ); } add_action('execute_nextjs_revalidate', 'trigger_nextjs_update'); function trigger_nextjs_update($slug) { $secret = getenv('NEXTJS_REVALIDATE_SECRET'); $url = getenv('NEXTJS_SITE_URL') . "/api/revalidate?secret={$secret}"; wp_remote_post($url, [ 'headers' => ['Content-Type' => 'application/json'], 'body' => json_encode(['slug' => $slug]), ]); }
方案3:WP GraphQL + Next.js(灵活数据获取)
如果需要更复杂的内容查询(如关联字段、自定义文章类型),可以使用WP GraphQL插件:
步骤1:WordPress启用GraphQL
安装WP GraphQL插件,确保自定义文章类型开启GraphQL支持(注册时设置show_in_graphql => true)。
步骤2:Next.js 用GraphQL获取数据
使用graphql-request库实现数据拉取:
import { request, gql } from 'graphql-request'; export async function getStaticProps({ params }) { const query = gql` query GetPost($slug: String!) { postBy(slug: $slug) { title content slug categories { nodes { name } } } } `; const data = await request( 'https://your-wp-site.com/graphql', query, { slug: params.slug } ); if (!data.postBy) return { notFound: true }; return { props: { post: data.postBy }, revalidate: 60, }; }
Webhook触发逻辑与方案1一致,仅需调整数据拉取方式。
关键注意事项
- 密钥安全:将验证密钥存入环境变量(WordPress用
wp-config.php的define,Next.js用.env),禁止硬编码。 - 自定义内容类型:若同步自定义文章类型,需在WordPress中开启REST/GraphQL支持。
- 删除内容处理:添加
delete_post钩子,调用Next.js API标记对应页面为404。 - 请求验证:在Next.js的Webhook路由中验证请求来源,防止恶意触发。
内容的提问来源于stack exchange,提问作者Yagnik Siddhapura
相关产品推荐
相关产品推荐

