如何将WordPress用作Next.js的无头内容管理系统

如何将WordPress用作Next.js的无头内容管理系统

根据 W3Techs 的数据,WordPress 已经存在了 20 多年,为互联网上 42.7% 的网站提供动力。在网站内容管理系统(CMS)方面,WordPress 也占据了 62.5% 的市场份额。

如今,许多编程语言和框架都可以用来构建用户友好的高性能网站,无论您在 WordPress 仪表板上做什么优化,它们的速度都比 WordPress 快得多。其中一个例子就是流行的 React 框架 Next.js

本指南展示了如何将 WordPress 用作无头 CMS,为 Next.js 应用程序提供数据。它还介绍了如何将 Next.js 代码作为静态网站部署到静态网站托管服务器。

了解无头 WordPress

无头WordPress指的是只使用WordPress的后台功能(管理和存储内容),而使用单独的系统(如Next.js)来展示前端。

这种解耦允许开发人员使用 WordPress 强大的内容管理工具,同时充分利用现代前端开发功能,如 Next.js 中的服务器端渲染和静态网站生成。

准备您的 WordPress 网站

在进行 Next.js 开发之前,您的 WordPress 网站需要做一些准备工作,才能作为无头内容管理系统使用。

拥有 WordPress 网站后,有两种方法可以将数据从 WordPress CMS 获取到前端框架中: WPGraphQL 和 REST API

REST API 便于使用 JavaScript 方法(如 Fetch APIAxios 库)以JSON格式检索数据。REST API从WordPress 4.7版本开始就内置于WordPress中,这意味着它不需要任何插件即可运行。但要使用 WPGraphQL(允许您使用 GraphQL 查询与 WordPress 数据交互),您必须安装 WPGraphQL 插件。

本指南将使用 REST API。要获取 JSON 格式的 WordPress 数据,请在 WordPress 网站 URL 中添加 /wp-json/wp/v2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
http://yoursite.com/wp-json/wp/v2
http://yoursite.com/wp-json/wp/v2
http://yoursite.com/wp-json/wp/v2

如果您在访问 http://yoursite.com/wp-json 时默认未启用 JSON API,您可以在 WordPress 面板的 “设置” 下打开 “固定链接“,然后选择 “文章名” 或除 “朴素” 之外的其他任一选项来启用它:

配置 WordPress REST API 以访问 JSON 数据

配置 WordPress REST API 以访问 JSON 数据

这适用于本地和公共 WordPress 网站,为包括文章页面评论媒体在内的内容提供端点。阅读我们的 REST API 完整指南,了解更多信息。

设置 Next.js 环境

Next.js 可帮助开发人员轻松构建网络应用程序,提高性能并优化开发体验。它的主要功能之一是基于文件的路由,可简化路由的创建。

此外,Next.js 还非常注重性能,提供了自动代码拆分等功能,只加载每个页面所需的 JavaScript,大大缩短了加载时间。

要建立一个 Next.js 项目,可以运行以下命令并使用其默认响应:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npx create-next-app@latest nextjs-wp-demo
npx create-next-app@latest nextjs-wp-demo
npx create-next-app@latest nextjs-wp-demo

在本指南中,您可以按照以下步骤获取我们的 Git 启动模板:

  1. 访问本项目的 GitHub 仓库
  2. 选择 “Use this template > Create a new repository“,将启动代码复制到 GitHub 账户中的仓库(选中复选框以 include all branches)。
  3. 将仓库拉到本地电脑,然后使用命令切换到 starter-files 分支: git checkout starter-files
  4. 运行 npm install 命令安装必要的依赖项。

安装完成后,在本地电脑上使用 npm run dev 启动项目。这样,项目就可以在 http://localhost:3000/ 上运行了。

使用 Next.js 构建的启动项目截图

使用 Next.js 构建的启动项目截图

了解项目

应用路由器在 Next.js 13 中引入,取代了现有的用于路由的 pages 目录。使用 App Router 设置路由还包括在 app 目录中创建文件夹。然后,在相应的文件夹中嵌套一个 page.js 文件,以定义路由。

在本项目中,app 是与之交互的核心目录,文件结构如下。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/
|-- /app
|-- /blog
|-- /[postId]
|-- page.js
|-- page.js
|-- globals.css
|-- layout.js
|-- navbar.js
|-- page.js
/ |-- /app |-- /blog |-- /[postId] |-- page.js |-- page.js |-- globals.css |-- layout.js |-- navbar.js |-- page.js
/
|-- /app
|-- /blog
|-- /[postId]
|-- page.js
|-- page.js
|-- globals.css
|-- layout.js
|-- navbar.js
|-- page.js

我们创建了三个页面:主页用于显示基本信息,博客页面用于显示 WordPress CMS 中的所有文章,动态页面([postId]/page.js)用于显示单个文章。

你还会注意到 navbar.js 组件,它被导入 layout.js 文件,为项目创建布局。

从 WordPress 向 Next.js 抓取数据

使用 WordPress REST API,您可以通过向特定端点发送 HTTP 请求来获取文章、页面和自定义文章类型。

让我们在 blog/page.js 文件中发出获取请求,获取 WordPress CMS 中的所有文章,最后再根据传递的 id 参数在 blog/[postId]/page.js 中发出请求,动态获取每个文章。

在发出这些请求之前,我们最好将 JSON API 地址添加到环境变量中。这种方法可以确保你的 API 基本 URL 易于配置,而不是在多个文件中硬编码。

在 Next.js 项目根目录下创建一个 .env 文件,并添加以下内容:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
NEXT_PUBLIC_WORDPRESS_API_URL=https://yoursite.kinsta.cloud/wp-json/wp/v2
NEXT_PUBLIC_WORDPRESS_API_URL=https://yoursite.kinsta.cloud/wp-json/wp/v2
NEXT_PUBLIC_WORDPRESS_API_URL=https://yoursite.kinsta.cloud/wp-json/wp/v2

确保将 URL 替换为网站的 JSON API。此外,在 .gitignore 文件中添加 .env 文件,这样它就不会将文件推送到 Git 提供商。

从 WordPress 获取所有文章到 Next.js

要从 WordPress 网站获取所有文章,请在 blog/page.js 文件中创建一个名为 getPosts 的异步函数。该函数使用 Fetch API 向 WordPress REST API 的 /posts 端点发出 GET 请求。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
async function getPosts() {
const response = await fetch(
`${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts`
);
const posts = await response.json();
return posts;
}
async function getPosts() { const response = await fetch( `${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts` ); const posts = await response.json(); return posts; }
async function getPosts() {
const response = await fetch(
`${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts`
);
const posts = await response.json();
return posts;
}

收到响应后,它会将响应转换为 JSON 格式,并建立一个文章对象数组。 这些posts 可以在 Next.js 应用程序中呈现,提供直接从 WordPress 获取的博客文章动态列表。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const BlogPage = async () => {
const posts = await getPosts();
return (
<div className="blog-page">
<h2>All Blog Posts</h2>
<p>All blog posts are fetched from WordPress via the WP REST API.</p>
<div className="posts">
{posts.map((post) => {
return (
<Link href={`/blog/${post.id}`} className="post" key={post.id}>
<h3>{post.title.rendered}</h3>
<p
dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }}
></p>
</Link>
);
})}
</div>
</div>
);
};
const BlogPage = async () => { const posts = await getPosts(); return ( <div className="blog-page"> <h2>All Blog Posts</h2> <p>All blog posts are fetched from WordPress via the WP REST API.</p> <div className="posts"> {posts.map((post) => { return ( <Link href={`/blog/${post.id}`} className="post" key={post.id}> <h3>{post.title.rendered}</h3> <p dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} ></p> </Link> ); })} </div> </div> ); };
const BlogPage = async () => {
const posts = await getPosts();
return (
<div className="blog-page">
<h2>All Blog Posts</h2>
<p>All blog posts are fetched from WordPress via the WP REST API.</p>
<div className="posts">
{posts.map((post) => {
return (
<Link href={`/blog/${post.id}`} className="post" key={post.id}>
<h3>{post.title.rendered}</h3>
<p
dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }}
></p>
</Link>
);
})}
</div>
</div>
);
};

在 Next.js 页面组件中,异步调用 getPosts 来获取文章。 然后,映射(mapposts 数组,在 <Link> 组件中呈现每个文章的 title 和 excerpt 。

这样不仅能显示文章,还能将每个文章封装在一个链接中,从而导航到文章的详细视图。这是通过使用 Next.js 基于文件的路由实现的,其中文章 ID 用于动态生成 URL 路径。

从 WordPress 向 Next.js 抓取动态文章

在上面的代码中,每个文章都被包裹在一个链接中,该链接可帮助用户导航到文章的详细视图。

对于单个文章页面,您可以利用 Next.js 中的动态路由创建一个页面,根据文章 ID 抓取并显示单个文章。在 stater-files 代码中已经创建了一个动态页面 [postID]/page.js

创建与 getPosts 类似的 getSinglePost 函数,使用作为参数传递的文章 ID 获取单个文章。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
async function getSinglePost(postId) {
const response = await fetch(
`${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts/${postId}`
);
const post = await response.json();
return post;
}
async function getSinglePost(postId) { const response = await fetch( `${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts/${postId}` ); const post = await response.json(); return post; }
async function getSinglePost(postId) {
const response = await fetch(
`${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts/${postId}`
);
const post = await response.json();
return post;
}

在动态页面组件中,你可以从 URL 参数中提取文章 ID,使用此 ID 调用 getSinglePost,然后呈现文章内容。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const page = async ({ params }) => {
const post = await getSinglePost(params.postId);
// ... the rest of the page code
};
const page = async ({ params }) => { const post = await getSinglePost(params.postId); // ... the rest of the page code };
const page = async ({ params }) => {
const post = await getSinglePost(params.postId);
// ... the rest of the page code
};

然后,您就可以用获取的数据填充页面:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const page = async ({ params }) => {
const post = await getSinglePost(params.postId);
if (!post) {
return <div>Loading...</div>;
}
return (
<div className="single-blog-page">
<h2>{post.title.rendered}</h2>
<div className="blog-post">
<p> dangerouslySetInnerHTML={{ __html: post.content.rendered }}></p>
</div>
</div>
);
};
const page = async ({ params }) => { const post = await getSinglePost(params.postId); if (!post) { return <div>Loading...</div>; } return ( <div className="single-blog-page"> <h2>{post.title.rendered}</h2> <div className="blog-post"> <p> dangerouslySetInnerHTML={{ __html: post.content.rendered }}></p> </div> </div> ); };
const page = async ({ params }) => {
const post = await getSinglePost(params.postId);
if (!post) {
return <div>Loading...</div>;
}
return (
<div className="single-blog-page">
<h2>{post.title.rendered}</h2>
<div className="blog-post">
<p> dangerouslySetInnerHTML={{ __html: post.content.rendered }}></p>
</div>
</div>
);
};

您可以从 GitHub 代码库中获取完整代码。

将 Next.js 应用程序部署到服务器

以 Kinsta 为例,您可以通过静态网站托管服务托管静态网站。

这项服务只托管静态文件。如果使用 Next.js 等静态网站生成器,可以配置选项,从 GitHub 构建项目并将静态文件部署到 Kinsta。

Next.js 中的静态呈现

要在 Next.js 13 以上版本中启用静态输出,请在 next.config.js 中更改 output 模式:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const nextConfig = {
output: 'export',
};
const nextConfig = { output: 'export', };
const nextConfig = {
output: 'export',
};

现在,当您构建项目时,Next.js 会生成一个包含应用程序 HTMLCSS 和 JavaScript 资产的 out 文件夹。

从第 13 版开始,Next.js 支持从静态网站开始,然后选择性地升级以使用需要服务器的功能。使用服务器功能时,创建的页面不会生成静态页面。

例如,在动态路由中,你要动态获取这些数据。您需要能够静态生成所有文章。这可以使用 generateStaticParams 函数来实现。

该函数与动态路由段结合使用,可在构建时静态生成路由,而不是在请求时按需生成。在构建时, generateStaticParams 会在生成相应布局或页面之前运行。

[postID]/page.js 中,使用 generateStaticParams 函数获取所有文章路由:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export async function generateStaticParams() {
const response = await fetch(
`${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts`
);
const posts = await response.json();
return posts.map((post) => ({
postId: post.id.toString(),
}));
}
export async function generateStaticParams() { const response = await fetch( `${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts` ); const posts = await response.json(); return posts.map((post) => ({ postId: post.id.toString(), })); }
export async function generateStaticParams() {
const response = await fetch(
`${process.env.NEXT_PUBLIC_WORDPRESS_API_URL}/posts`
);
const posts = await response.json();
return posts.map((post) => ({
postId: post.id.toString(),
}));
}

运行构建命令后,Next.js 项目将生成一个包含静态文件的 out 目录。

将 Next.js 部署到 Kinsta 静态网站托管中

将代码推送到首选的 Git 提供商(Bitbucket、GitHub 或 GitLab)。然后,按照以下步骤将 Next.js 静态网站部署到 Kinsta:

  1. 登录或创建账户,查看 MyKinsta 面板。
  2. 使用 Git 提供商授权 Kinsta。
  3. 单击左侧边栏上的 Static Sites,然后单击 Add site
  4. 选择要部署的版本库和分支。
  5. 为网站指定一个唯一的名称。
  6. 按以下格式添加构建设置:
    • 构建命令:npm run build
    • Node 版本:18.16.0
    • 发布目录:out
  1. 最后,点击 Create site

就这样!几秒钟后,您就拥有了一个已部署的站点。我们会提供一个链接,用于访问已部署的网站版本。随后,您可以根据需要添加自定义域名和 SSL 证书。

作为静态网站托管的替代方案,您可以选择使用 Kinsta 及合适的服务器提供商的应用程序托管服务来部署您的静态网站,它提供了更大的托管灵活性、更广泛的优势以及更强大的功能,例如可扩展性、使用 Dockerfile 进行自定义部署以及包含实时和历史数据的全面分析。您也无需为静态渲染配置 Next.js 项目。

小结

在本文中,您将学习如何在 Next.js 项目中利用无头 WordPress 动态获取和显示文章。这种方法可以将 WordPress 内容无缝集成到 Next.js 应用程序中,提供现代化的动态网络体验。

无头内容管理系统 API 的潜力不仅限于文章,它还允许检索和管理页面、评论、媒体等。

评论留言