根據 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 API 或 Axios 庫)以JSON格式檢索資料。REST API從WordPress 4.7版本開始就內建於WordPress中,這意味著它不需要任何外掛即可執行。但要使用 WPGraphQL(允許您使用 GraphQL 查詢與 WordPress 資料互動),您必須安裝 WPGraphQL 外掛。
本指南將使用 REST API。要獲取 JSON 格式的 WordPress 資料,請在 WordPress 網站 URL 中新增 /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 完整指南,瞭解更多資訊。
設定 Next.js 環境
Next.js 可幫助開發人員輕鬆構建網路應用程式,提高效能並優化開發體驗。它的主要功能之一是基於檔案的路由,可簡化路由的建立。
此外,Next.js 還非常注重效能,提供了自動程式碼拆分等功能,只載入每個頁面所需的 JavaScript,大大縮短了載入時間。
要建立一個 Next.js 專案,可以執行以下命令並使用其預設響應:
npx create-next-app@latest nextjs-wp-demo
在本指南中,您可以按照以下步驟獲取我們的 Git 啟動模板:
- 訪問本專案的 GitHub 倉庫。
- 選擇 “Use this template > Create a new repository“,將啟動程式碼複製到 GitHub 賬戶中的倉庫(選中覈取方塊以 include all branches)。
- 將倉庫拉到本地電腦,然後使用命令切換到 starter-files 分支:
git checkout starter-files
。 - 執行
npm install
命令安裝必要的依賴項。
安裝完成後,在本地電腦上使用 npm run dev
啟動專案。這樣,專案就可以在 http://localhost:3000/ 上執行了。
使用 Next.js 構建的啟動專案截圖
瞭解專案
應用路由器在 Next.js 13 中引入,取代了現有的用於路由的 pages 目錄。使用 App Router 設定路由還包括在 app 目錄中建立資料夾。然後,在相應的資料夾中巢狀一個 page.js 檔案,以定義路由。
在本專案中,app 是與之互動的核心目錄,檔案結構如下。
/ |-- /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 檔案,並新增以下內容:
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 請求。
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 獲取的部落格文章動態列表。
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
來獲取文章。 然後,對映(map
)posts
陣列,在 <Link>
元件中呈現每個文章的 title
和 excerpt
。
這樣不僅能顯示文章,還能將每個文章封裝在一個連結中,從而導航到文章的詳細檢視。這是通過使用 Next.js 基於檔案的路由實現的,其中文章 ID 用於動態生成 URL 路徑。
從 WordPress 向 Next.js 抓取動態文章
在上面的程式碼中,每個文章都被包裹在一個連結中,該連結可幫助使用者導航到文章的詳細檢視。
對於單個文章頁面,您可以利用 Next.js 中的動態路由建立一個頁面,根據文章 ID 抓取並顯示單個文章。在 stater-files 程式碼中已經建立了一個動態頁面 [postID]/page.js。
建立與 getPosts
類似的 getSinglePost
函式,使用作為引數傳遞的文章 ID 獲取單個文章。
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
,然後呈現文章內容。
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); 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
模式:
const nextConfig = { output: 'export', };
現在,當您構建專案時,Next.js 會生成一個包含應用程式 HTML、CSS 和 JavaScript 資產的 out 資料夾。
從第 13 版開始,Next.js 支援從靜態網站開始,然後選擇性地升級以使用需要伺服器的功能。使用伺服器功能時,建立的頁面不會生成靜態頁面。
例如,在動態路由中,你要動態獲取這些資料。您需要能夠靜態生成所有文章。這可以使用 generateStaticParams
函式來實現。
該函式與動態路由段結合使用,可在構建時靜態生成路由,而不是在請求時按需生成。在構建時, generateStaticParams
會在生成相應佈局或頁面之前執行。
在 [postID]/page.js 中,使用 generateStaticParams
函式獲取所有文章路由:
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:
- 登入或建立賬戶,檢視 MyKinsta 面板。
- 使用 Git 提供商授權 Kinsta。
- 單擊左側邊欄上的 Static Sites,然後單擊 Add site。
- 選擇要部署的版本庫和分支。
- 為網站指定一個唯一的名稱。
- 按以下格式新增構建設定:
- 構建命令:
npm run build
- Node 版本:
18.16.0
- 釋出目錄:
out
- 構建命令:
- 最後,點選 Create site。
就這樣!幾秒鐘後,您就擁有了一個已部署的站點。我們會提供一個連結,用於訪問已部署的網站版本。隨後,您可以根據需要新增自定義域名和 SSL 證書。
作為靜態網站託管的替代方案,您可以選擇使用 Kinsta 及合適的伺服器提供商的應用程式託管服務來部署您的靜態網站,它提供了更大的託管靈活性、更廣泛的優勢以及更強大的功能,例如可擴充套件性、使用 Dockerfile 進行自定義部署以及包含實時和歷史資料的全面分析。您也無需為靜態渲染配置 Next.js 專案。
小結
在本文中,您將學習如何在 Next.js 專案中利用無頭 WordPress 動態獲取和顯示文章。這種方法可以將 WordPress 內容無縫整合到 Next.js 應用程式中,提供現代化的動態網路體驗。
無頭內容管理系統 API 的潛力不僅限於文章,它還允許檢索和管理頁面、評論、媒體等。
評論留言