
无头 WordPress 解锁了许多强大的用例,这些用例使用传统架构通常难以构建或效率较低。例如,开发人员和设计师可能会受到 WordPress 主题结构的限制。无头方法完全消除了这些限制。无头架构在速度至关重要的领域也表现出色,例如高流量网站、新闻门户和电子商务商店。多渠道内容交付是无头网站最强大的用例之一。所有内容都在熟悉的 WordPress 管理面板中进行管理,然后通过 GraphQL 或 REST API 公开给任何可以发出 HTTP 请求的平台。
在本文中,我们将从头开始创建一个无头 WordPress 网站。然而,我们并不是真的要完全从零开始构建它。就像你可以使用插件样板加速插件创建一样,你可以通过使用蓝图更快地构建无头网站。
什么是无头 WordPress?
传统的 WordPress 是一个"单体"CMS。换句话说,你创建文章和管理内容的后端与向访问者展示内容的前端主题紧密耦合。
无头 WordPress 将这两个部分解耦。你的 WordPress 安装成为一个纯内容存储库。你仍然可以使用熟悉且强大的 WordPress 管理面板来创建、编辑和管理所有内容,但面向公众的网站是一个完全独立的应用程序,使用 React 或 Next.js 等现代 JavaScript 框架构建。这个应用程序负责整个视觉呈现和用户体验。
这两个部分通过 API 进行通信。前端向 WordPress 后端请求内容,WordPress 将其作为结构化数据提供。
WP Engine 无头平台
虽然你可以在任何托管服务上构建无头架构,但 WP Engine 无头平台 是专门为消除复杂性而构建的。它通过从单一统一仪表板管理你的 WordPress 后端和 Node.js 前端应用程序,提供一个连贯的优化环境。
这种简化的工作流程通过 Faust.js 框架 和基于 Git 的部署等以开发者为中心的工具得到进一步增强,让你能够更快、更高效地构建。
性能至关重要,该平台采用全球分布式 CDN 和优化的 Node.js 服务器,为用户提供预期的亚秒级页面加载速度。这种对速度的重视伴随着对安全性的承诺。解耦架构本质上减少了网站的攻击面,WP Engine 还叠加了其监控和威胁检测功能来保护你的应用程序。
我们将构建什么
在本指南中,我们将创建一个简单但功能完整的博客,作为可随时部署的无头网站。该网站将包含一个列出博客文章的主页,点击文章后,用户将进入该特定文章的动态单独页面。
设置你的工具箱
在开始构建网站之前,让我们确保你准备好所有必要的工具和账户。
- WP Engine 账户: 您需要一个有效的 WP Engine 账户,并订阅 Headless 平台套餐。此特定套餐是必需的,因为它同时提供用于我们后端的托管 WordPress 安装和用于前端应用的专用 Node.js 托管环境。
- Node.js 和 npm: 现代 JavaScript 开发运行在 Node.js 之上。我们建议从官方网站 Node.js website 下载并安装最新的长期支持(LTS)版本。Node.js 自带 npm(Node 包管理器),我们将用它来安装和管理项目的代码包。
- Git: WP Engine Headless 平台使用 Git 作为部署引擎。您需要在电脑上安装 Git,以便将完成的代码推送到 WP Engine 的服务器并上线您的站点。您可以从官方网站 Git website 下载。
- 代码编辑器: 实际上您并不需要代码编辑器。如果您愿意,可以使用简单的文本编辑器编辑所有文件。Visual Studio Code 是免费的,效果很好,并且内置了终端。
在 WP Engine 上配置后端
工具准备就绪后,我们的第一个实践任务是设置 WordPress 内容后端。WP Engine Headless 平台提供了简化的工作流程,让您从预配置的蓝图开始,同时设置后端和启动前端项目。
从蓝图启动新项目
首先,登录您的 WP Engine 用户门户。从主导航菜单中,找到并点击 Headless 选项卡。 您将看到两个选项:"Start with Blueprint"和"Pull from repository"。蓝图是一个启动工具包,会配置您需要的一切。由于我们正在创建新项目,这是一个不错的选择。

点击 Start with Blueprint 按钮。您将看到可用的蓝图,包括"Portfolio"和"Shopify"等选项。我们将选择"Scaffolding"蓝图。正如其描述所述,此选项提供了快速启动新项目的基本要素,不会强制使用预设计的主题。
选择 Scaffolding 蓝图。然后系统将提示您连接到 Git 仓库,可在 GitHub、Bitbucket 和 GitLab 之间进行选择。在这种情况下,我们将使用 GitHub。连接到 Git 仓库基本上就是按照提示操作。设置完成后,决定是否要将仓库设为私有,然后选择您的区域。接下来,点击 Add app 进入下一阶段。

此过程可能需要几分钟才能完成,因为 WP Engine 正在配置您的 WordPress 后端,并在您连接的 GitHub 账户中创建新的"Scaffolding"启动仓库。
访问您的 WordPress 后端
创建过程完成后,您将进入新应用的"Overview"页面。在这里您将看到刚刚创建的两个核心组件:用于前端的 GitHub 仓库(在"Source"下)和用于后端的 WordPress 环境(在"Environment details"下)。

点击 WordPress 环境打开其专属仪表板。在此页面中,您将找到有关后端的重要信息。点击 WP Admin 链接可直接跳转到您新 WordPress 网站的管理后台。初始管理员用户名和密码已自动生成,但您可能需要更改它。
创建内容
WordPress 仪表板非常熟悉。对于本项目,它的作用仅是管理内容。我们不会安装任何前端主题或外观相关的插件。
在添加内容之前,让我们先验证一些关键组件。从左侧菜单导航到 Plugins。您应该能看到 WPGraphQL 和 WPGraphQL for ACF 插件已经安装并激活,Advanced Custom Fields 和 Faust.js 也已安装并激活。WP Engine 的 Headless 平台使用 ACF 进行内容建模,所以我们绝对需要它。Faust.js 充当 WordPress 后端和前端应用程序之间的中间层。
接下来,我们需要在后端创建一些文章,以便在前端显示内容。您可以使用真实文章、编造一些无意义的内容,或使用 WP Dummy Content Generator 插件。
无论使用哪种方法,提前准备好这些内容对下一阶段至关重要,因为我们将构建前端来获取并显示这些内容。
使用 Faust.js 构建前端
我们在上一步中使用的 "Scaffolding" 蓝图不仅创建了 WordPress 安装,还在我们 GitHub 账户中创建了一个包含初始前端项目的新仓库。该项目使用 Faust.js 构建,这是 WP Engine 的开源框架,专为简化无头 WordPress 开发而设计。
什么是 Faust.js?
Faust.js 是基于流行的 React 框架 Next.js 构建的框架。虽然您可以使用任何 JavaScript 框架来构建无头网站,但强烈建议在使用 WP Engine Headless 平台时使用 Faust.js,因为它提供了开箱即用的解决方案来应对常见挑战,包括简化从 WordPress WPGraphQL API 获取数据、现成的模板创建系统,以及与 WordPress 预览引擎的集成。
本质上,Faust.js 处理复杂的底层工作,让您可以专注于构建网站的主题和组件。
克隆和探索项目
我们的第一步是将新 Git 仓库中的初始代码获取到本地计算机上。
导航到您使用的 Git 账户,找到 WP Engine 为您创建的新仓库(它应该以您项目命名的名称命名)。如果使用 GitHub,点击 <> Code 按钮,确保选中 "HTTPS" 选项卡,然后复制仓库 URL。
打开计算机的终端(或 VS Code 中的集成终端),导航到您存储项目的目录,然后运行以下命令,将 URL 替换为您复制的 URL:
git clone https://github.com/your-username/my-headless-blog.git
克隆完成后,进入新项目目录:
cd my-headless-blog
现在,使用 npm 安装所有必要的项目依赖。以下命令会安装项目 package.json 文件中列出的所有依赖。
npm install
npm install 完成后,您可以在 VS Code 中打开整个项目文件夹来探索其结构。

解决关键文件冲突
运行 git clone 命令后,您可能会在终端中看到一条重要的警告消息,内容如下:
警告:以下路径存在冲突(例如,大小写敏感路径
在大小写不敏感的文件系统上),且同一
冲突组中只有一个在工作树中:
'components/Footer.js'
'components/footer.js'
'components/Header.js'
'components/header.js'
发生这种情况是因为蓝图 的 Git 仓库是大小写敏感的,包含文件名相同但大小写不同的文件(例如,Header.js 和 header.js)。然而,您计算机的文件系统(macOS 或 Windows)可能是大小写不敏感的,将这些视为同一个文件,从而导致冲突。这可能导致项目文件夹中缺少一个或两个文件。
幸运的是,修复方法很简单。我们只需要告诉 Git 从其跟踪系统中删除这些错误的小写版本的文件。
首先,确保您已使用 cd my-headless-blog 命令进入新项目目录(将 my-headless-blog 替换为您的项目文件夹名称)。
接下来,运行以下两个命令来从 Git 的跟踪中删除冲突的文件:
git rm components/footer.js
git rm components/header.js
接下来,我们将此修复提交到本地 Git 历史记录。这将保存更改,并确保我们的项目处于稳定状态。
git commit -m "Fix file case collision from blueprint"
文件冲突已解决,修复已提交,您的项目文件夹现在处于干净、稳定的状态,您可以继续进行下一步了。
将前端连接到 WordPress
本节中最关键的步骤是告诉我们的本地前端应用程序在哪里找到 WordPress 后端以及如何安全地进行身份验证。此连接使用名为“环境文件”的特殊配置文件进行管理。
首先,我们需要从 WordPress 后端收集两条信息:站点 URL 和唯一的密钥。
在 WordPress 中查找您的凭据
- 查找您的 WordPress URL: 登录到您的 WordPress 管理仪表板。在左侧菜单中,导航到 设置 > 常规。从 站点地址 (URL) 字段复制 URL。这是您的 WordPress 后端的基础 URL(例如,
https://myheadlessblog.wpengine.com)。 - 查找您的 Faust.js 密钥: 此密钥对于授权前端和后端之间的请求至关重要。在您的 WordPress 管理后台,点击左侧菜单中的 Faust 选项卡。在此设置页面上,您将看到一个标记为“Secret Key”的字段。复制此字符串。
创建您的本地环境文件
现在我们有了凭据,让我们将它们添加到您的项目中。在项目文件夹的根目录中,您将找到一个名为 .env.local.sample 的文件。这是您的配置模板。
创建此文件的副本,并将副本重命名为 .env.local。.local 扩展名是一个特殊约定,确保此文件加载到您的本地环境中,但会被 Git 忽略,从而保护您的密钥安全。
在代码编辑器中打开新的 .env.local 文件。删除任何现有内容并替换为以下内容,粘贴您刚刚从 WordPress 复制的 URL 和密钥。
# This is the "Site Address (URL)" from your WordPress General Settings.
# Do NOT add /graphql or a slash to the end of it.
NEXT_PUBLIC_WORDPRESS_URL="https://myheadlessblog.wpengine.com"
# This is the secret key from the FaustWP plugin settings page in WordPress.
FAUST_SECRET_KEY="paste-the-long-secret-key-you-found-here"
保存 .env.local 文件。正确配置此文件后,您的前端应用程序现在应该拥有安全连接到 WordPress 后端和获取数据所需的一切。
本地运行应用程序
下载并配置项目后,您已准备好查看它的运行情况。在终端中,从项目目录的根目录运行以下命令:
npm run dev
这将启动本地开发服务器。稍等片刻,您应该会看到一条消息,表明服务器正在运行。现在您可以打开Web浏览器并访问 http://localhost:3000。
如果一切连接正确,您应该会看到一个 Faust.js 样板网站。我们将在下一节开始获取和显示我们自己的内容。
获取和显示内容
现在我们的本地前端已连接到 WordPress 后端,我们可以开始获取内容并显示它。Faust.js 的“脚手架”蓝图已经为此设置好了基本文件,我们现在将对其进行自定义。
我们将只关注一个关键文件,即控制我们网站首页的 /wp-templates/front-page.js。
自定义博客索引页面
让我们修改我们网站的首页,以显示清晰的帖子列表,包括标题、摘要和特色图片。
我们知道主首页由 /wp-templates/front-page.js 控制,因此请在代码编辑器中打开此文件。我们将用获取和显示博客帖子的代码替换其内容。
将 /wp-templates/front-page.js 的全部内容替换为以下代码:
import { gql } from '@apollo/client';
import Head from 'next/head';
import Link from 'next/link';
import Image from 'next/image';
import Header from '../components/Header';
import Footer from '../components/Footer';
export default function Component(props) {
// Loading state
if (props.loading) {
return <>Loading...</>;
}
// Get data, using optional chaining to protect against errors
const { title, description } = props.data?.generalSettings ?? {};
const posts = props.data?.posts?.nodes;
return (
<>
<Head>
<title>{title}</title>
</Head>
<Header title={title} description={description} />
<main className="container">
{posts && posts.length > 0 ? (
<div className="posts-list">
{posts.map((post) => (
<article key={post.id} className="post-item">
{post.featuredImage && (
<Link href={`/${post.slug}`}>
<Image
src={post.featuredImage.node.sourceUrl}
alt={post.featuredImage.node.altText || post.title}
width={post.featuredImage.node.mediaDetails.width}
height={post.featuredImage.node.mediaDetails.height}
className="featured-image"
/>
</Link>
)}
<h2>
<Link href={`/${post.slug}`}>
{post.title}
</Link>
</h2>
<div
className="post-excerpt"
dangerouslySetInnerHTML={{ __html: post.excerpt }}
/>
</article>
))}
</div>
) : (
<p>No posts found.</p>
)}
</main>
<Footer copyrightHolder={title} />
</>
);
}
Component.query = gql`
query GetHomePage {
generalSettings {
title
description
}
posts(first: 100) {
nodes {
id
title
slug
excerpt
featuredImage {
node {
sourceUrl
altText
mediaDetails {
height
width
}
}
}
}
}
}
`;
这段代码的工作原理是首先定义从 WordPress 获取所需数据,然后使用 React 组件渲染该数据。在文件底部,Component.query 静态属性定义了一个 GraphQL 查询。该查询告诉 WordPress 要返回哪些数据,请求 generalSettings(用于网站标题和标语)以及 posts 列表。
我们请求 posts(first: 100),因为许多 GraphQL 服务器要求你指定一个限制,以防止意外一次请求数千个项目。对于每个帖子,我们请求所有需要的数据,包括 id、title、用于 URL 的 slug、excerpt,以及带有 URL 和尺寸的 featuredImage。
主 Component 函数通过其 props 接收此查询的结果。为了防止我们之前看到的运行时错误,代码使用一种名为 可选链(?.)的现代 JavaScript 特性安全地提取数据。const posts = props.data?.posts?.nodes; 这行代码确保即使响应中缺少 data 或 posts 对象,应用也不会崩溃。然后组件检查 posts 数组是否实际包含任何项目。如果不包含,它会显示"No posts found."(未找到帖子)消息,这有助于调试。
如果帖子确实存在,代码使用标准的 .map() 方法遍历数组中的每个 post 并为其渲染一个单独的 <article>。为了创建指向完整帖子的链接,每个标题都包裹在 Next.js 的 <Link> 组件中。最后,为了正确显示帖子摘要,我们使用一个名为 dangerouslySetInnerHTML 的特殊 React 属性。这是因为来自 WordPress 的内容(如摘要)通常包含自己的 HTML 标签(如 <p>...</p>),而这个属性告诉 React 呈现原始 HTML 而不是将其视为纯文本。尝试点击一个标题——它可能会导致"404 Not Found"页面或目前样式不同的页面。我们稍后会修复这个问题。
构建单个帖子页面
现在我们的首页正确列出了所有帖子,我们需要确保点击帖子后,用户会进入一个正确格式化的页面,显示该帖子的完整内容。
正如 /wp-templates/front-page.js 控制首页一样,Faust.js 模板系统会查找名为 /wp-templates/single.js 的文件来渲染单个帖子。"Scaffolding"蓝图可能没有为我们创建这个文件,所以我们将创建它并添加必要的代码。
如果你有 /pages/[postSlug].js 或 /pages/[...wordpressNode].js 文件,你可以删除它以避免混淆,因为 /wp-templates/single.js 将优先于你的帖子。
在你的 /wp-templates 目录中创建一个名为 single.js 的新文件。将以下代码粘贴到其中:
import { gql } from '@apollo/client';
import Head from 'next/head';
import Link from 'next/link';
import Image from 'next/image';
import Header from '../components/Header';
import Footer from '../components/Footer';
export default function Component(props) {
// Loading state
if (props.loading) {
return <>Loading...</>;
}
// Get data for the post and site
const { post, generalSettings } = props.data;
// Handle case where post is not found
if (!post) {
return (
<>
<Header title="Not Found" description="Could not find the requested post." />
<main className="container">
<p>The post you were looking for could not be found.</p>
<Link href="/">
Return to the homepage
</Link>
</main>
<Footer copyrightHolder={generalSettings.title} />
</>
);
}
// Format the date
const postDate = new Date(post.date).toLocaleDateString('en-us', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
return (
<>
<Head>
<title>{post.title} - {generalSettings.title}</title>
</Head>
<Header title={generalSettings.title} description={generalSettings.description} />
<main className="container">
<article className="post-content-single">
<h1>{post.title}</h1>
<p className="post-meta">
By {post.author.node.name} on {postDate}
</p>
{post.featuredImage && (
<Image
src={post.featuredImage.node.sourceUrl}
alt={post.featuredImage.node.altText || post.title}
width={post.featuredImage.node.mediaDetails.width}
height={post.featuredImage.node.mediaDetails.height}
className="featured-image"
/>
)}
<div
dangerouslySetInnerHTML={{ __html: post.content }}
/>
</article>
<p style={{ marginTop: '2rem' }}>
<Link href="/">
← 返回所有文章
</Link>
</p>
</main>
<Footer copyrightHolder={generalSettings.title} />
</>
);
}
Component.query = gql`
query GetPost($databaseId: ID!, $asPreview: Boolean = false) {
post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {
title
content
date
author {
node {
name
}
}
featuredImage {
node {
sourceUrl
altText
mediaDetails {
height
width
}
}
}
}
generalSettings {
title
description
}
}
`;
Component.variables = ({ databaseId }, ctx) => {
return {
databaseId,
asPreview: ctx?.asPreview,
};
};
这段代码与我们的首页模板类似,但有一些关键区别。GraphQL 查询设计为使用 databaseId 作为唯一标识符来获取单个 post。这是一种比使用文章 slug 更可靠的方法。我们还请求了更多数据,比如完整的 content 和作者的姓名。最重要的是,底部的 Component.variables 函数使这个动态模板能够工作;它从页面的上下文中获取被请求文章的 ID,并将其传递给 GraphQL 查询。
在组件内部,我们安全地访问数据,甚至包含了检查是否找到文章的逻辑。如果没有找到,我们会显示一条有用的“未找到”消息。其余代码则渲染文章的标题、元数据、特色图片和完整内容,再次使用 dangerouslySetInnerHTML 来正确显示来自 WordPress 的 HTML。我们还使用现代的 Next.js <Link> 语法包含了一个“返回所有文章”链接。
将此文件保存为 /wp-templates/single.js 后,您的开发服务器将检测到它。现在,当您访问 http://localhost:3000 的首页并点击任何文章的标题或图片时,您将被带到一个为该特定文章完整渲染的页面。

为首页添加特色图片
到目前为止,我们已经成功地创建了一堵文字墙。它功能齐全,但非常无聊。为每篇文章引入特色图片将使我们的无头项目更加生动和吸引人。这个过程遵循我们已建立的模式:更新 GraphQL 查询以请求新数据,然后更新我们的组件来显示它。
更新 GraphQL 查询
首先,我们需要编辑 /wp-templates/front-page.js 中的查询,为每篇文章请求特色图片信息。最佳实践是不仅请求图片 URL,还要请求其 altText 以实现无障碍访问,以及其 mediaDetails 以进行尺寸调整。
在您的 /wp-templates/front-page.js 文件中,找到底部的 Component.query,将 featuredImage 对象添加到 nodes 字段中,如下所示:
// ... 在 Component.query 内部 ...
posts(first: 100) {
nodes {
id
title
slug
excerpt
featuredImage {
node {
sourceUrl
altText
mediaDetails {
height
width
}
}
}
}
}
// ...
渲染图片组件
现在我们的查询正在获取图片数据,我们可以渲染它了。我们将使用内置的 Next.js <Image> 组件,因为它具有性能优势,如自动图片优化和懒加载。
首先,将 Image 添加到 /wp-templates/front-page.js 顶部的导入列表中:
import Image from 'next/image';
接下来,找到组件中的 posts.map() 循环。我们将在 <article> 标签内、<h2> 标题之前添加 <Image> 组件。我们还将用 <Link> 包装它,这样点击图片就会导航到文章。重要的是添加条件检查(post.featuredImage && ...)以防止文章没有设置特色图片时出现错误。
进行这些更改后,你的 posts.map() 循环应该如下所示:
//...
{posts.map((post) => (
<article key={post.id} className="post-item">
{post.featuredImage && (
<Link href={`/${post.slug}`}>
<Image
src={post.featuredImage.node.sourceUrl}
alt={post.featuredImage.node.altText || post.title}
width={post.featuredImage.node.mediaDetails.width}
height={post.featuredImage.node.mediaDetails.height}
/>
</Link>
)}
<h2>
<Link href={`/${post.slug}`}>
{post.title}
</Link>
</h2>
<div
className="post-excerpt"
dangerouslySetInnerHTML={{ __html: post.excerpt }}
/>
</article>
))}
//...
保存此文件后,你的应用程序将尝试重新加载,但会立即崩溃并显示一个错误。这是预期行为。这个错误是 Next.js 的安全功能,我们将在下一步修复它。
配置图片域名
当页面重新加载时,你将看到一个运行时错误,显示:hostname "..." is not configured under images in your next.config.js。
这是 Next.js <Image> 组件的内置安全功能。为了防止滥用,Next.js 要求你明确“允许”所有计划从中加载图片的外部域名。我们需要告诉我们的应用程序,从我们的 WP Engine 站点加载图片是安全的。
在项目的根目录中,找到并打开名为 next.config.js 的文件。用以下代码替换其内容。这将为你的 WP Engine 域名添加必要的批准。一定要将 myheadlessblog.wpengine.com 替换为你实际的 WordPress 主机名。
const { withFaust } = require('@faustwp/core');
/** @type {import('next').NextConfig} */
module.exports = withFaust({
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'myheadlessblog.wpengine.com', // <-- 替换这个
port: '',
pathname: '/wp-content/uploads/**',
},
],
},
});
这是关键的一步。保存 next.config.js 文件后,你必须完全停止并重新启动你的开发服务器。此配置文件只在服务器首次启动时读取。转到你的终端,按 Ctrl+C 停止服务器,然后再次运行 npm run dev 重新启动它。
服务器重启后,错误将会消失,你的特色图片将正确加载,尽管它们可能非常大且没有样式。
使用 CSS 设置特色图片的样式
现在图片正在加载,我们可以使用 CSS 来控制它们的大小和外观。我们将为图片分配一个类名,然后在我们项目的全局样式表中为该类定义样式。
分配 CSS 类
在你的 /wp-templates/front-page.js 文件中,再次找到 <Image> 组件并向其添加 className 属性。
// ...
<Image
src={post.featuredImage.node.sourceUrl}
alt={post.featuredImage.node.altText || post.title}
width={post.featuredImage.node.mediaDetails.width}
height={post.featuredImage.node.mediaDetails.height}
className="featured-image" // <-- 添加这一行
/>
// ...
添加 CSS 规则
现在,打开位于 /styles/globals.css 的全局样式表,并将以下 CSS 代码块添加到文件底部。
/* Styles for our Featured Images on the homepage */
.post-item .featured-image {
width: 100%;
height: 250px; /* You can change this height to whatever you like */
object-fit: cover; /* This prevents the image from being stretched or squished */
display: block;
margin-bottom: 1rem; /* Adds some space between the image and the title */
border-radius: 8px; /* Optional: gives the images nice rounded corners */
}
这段 CSS 告诉浏览器让图片占据其容器的全部宽度,但保持固定高度 250px,并通过裁剪使图片整齐地适配而不变形(object-fit: cover)。
保存这两个文件后,浏览器将刷新,你应该能看到你的文章列表,每篇文章都配有尺寸完美且样式精美的特色图片。

总结
我们已经成功创建了一个无头 WordPress 站点,但看起来我们似乎投入了大量精力去做一件用传统单体 WordPress 更容易完成的事情。然而,我们所创建的是一个坚实的基础,可以用于从 WordPress 获取和显示任何类型的内容,包括文章、特色图片和全局站点设置。
把这个项目当作一个起点。在此基础上,你可以用不同的方式进行扩展。例如,你可以更深入地研究 /styles/globals.css 文件来创建真正独特的设计,或者你可以集成 Tailwind CSS 这样的框架来加速你的样式工作流程。要构建站点的完整用户界面,你可以创建一个动态的 <Nav> 组件,通过 GraphQL 从 WordPress 查询菜单数据来渲染站点的导航。
除了视觉上的变化,你还可以通过创建新的内容类型来极大地扩展站点的功能。使用预装的 Advanced Custom Fields 插件,你可以超越“文章”,创建“作品集项目”、“团队成员”或“产品”等结构化内容,所有这些都可以通过新的 GraphQL 查询来获取。为了进一步改善内容管理体验,你可以探索 Faust.js 最强大的功能之一:启用文章预览。虽然这需要一些额外的配置,但这个功能可以让你的内容团队在点击“发布”之前直接在前端看到他们的草稿内容,从而提供无缝的工作流程。
你构建过无头站点吗?你是从头开始真正构建的,还是使用模板/启动项目来加速这个过程?请在评论中告诉我们!




