如何將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 的潛力不僅限於文章,它還允許檢索和管理頁面、評論、媒體等。

評論留言