如何用React.js建立一個無頭的WordPress網站

如何用React.js建立一個無頭的WordPress網站

WordPress是最流行的內容管理系統(CMS)之一,有8.1億人在使用–佔整個網際網路的41%!它是任何想快速建立網站的人的首選,因為它簡單易行,提供廣泛的定製選項,也有強大的外掛和其他資源!它是任何想快速建立一個網站的人的首選,因為它簡單、使用者友好,提供各種各樣的定製選項,而且還有一個強大的外掛和其他資源的生態系統。

讓WordPress發揮最大作用的一個方法是採用無頭的方式。

無頭CMS,也被稱為無頭系統,是一種只用於管理內容的後臺CMS。這有助於你將內容整合到任何系統或網站中,只需呼叫無頭CMS的API

然而,這使得前端需要單獨管理。這就是API的作用。

API允許兩個或多個不同的應用程式交換資料。在這種情況下,API被用來將資料從CMS傳輸到前端網站,提供更多的靈活性和更快的效能

在這篇文章中,我們將探討什麼是無頭CMS,為什麼你可能想建立一個,以及如何使用React為WordPress設定一個。

  1. 什麼是無頭的WordPress?
  2. 無頭WordPress的優點和缺點
  3. 什麼是WordPress REST API?
  4. 什麼是React?
  5. 如何用React建立一個無頭的WordPress網站

什麼是無頭的WordPress?

無頭WordPress網站是一種主要使用WordPress作為CMS,即內容管理系統,並在前端使用其他前端技術,如React或Vue。

JavaScript庫和框架是用來顯示網站內容的。因此,無頭的WordPress有一個獨立的前端和後端,並使用API進行通訊。

更簡單地說,無頭架構意味著CMS只用於儲存和管理你的內容,它並不關心網站的前端。

另一方面,前端的主要工作是顯示內容,而它又不關心內容是在哪裡儲存或管理的,只要它能到達。

一個無頭的WordPress有更好的效能,因為前端的請求是由更快的技術(如React)處理的,而只有後端是由WordPress管理的。前臺和後臺的分離使得獨立擴充套件元件成為可能。

無頭WordPress的優點和缺點

與所有的開發選項一樣,使用無頭的WordPress解決方案既有好處也有壞處。在做出決定之前,瞭解這兩點是很重要的。

無頭WordPress的優點

無頭WordPress實施的一些主要好處包括以下幾點:

  • 靈活性:無頭WordPress允許開發人員建立自定義的前端體驗,而不受傳統WordPress主題系統的限制。這意味著你可以為特定需求建立獨特的使用者介面和體驗。
  • 效能:將WordPress網站的前端和後端分開,可以使你的網站載入更快,提高網站的效能,因為伺服器只是通過API傳遞資料,而不是為每個請求渲染HTML。
  • 安全性:通過分離前端和後端,無頭WordPress可以通過限制對底層WordPress程式碼庫和資料庫的訪問,提供額外的安全層。

無頭WordPress的缺點

無頭WordPress的缺點可能包括:

  • 缺少主題:由於無頭的WordPress不依賴預建的主題,你將需要建立你自己的自定義主題。這可能很耗時,而且可能需要額外的資源。
  • 成本:開發一個無頭WordPress網站可能比傳統的WordPress網站更昂貴,因為它需要更多的技術專長和資源來設定和維護。
  • 外掛限制:一些WordPress外掛可能無法在無頭WordPress中使用,因為它們需要依靠WordPress主題才能正常執行。

什麼是WordPress REST API?

WordPress REST API被用作後臺和前臺之間的介面。通過API,可以輕鬆地從網站上傳送或檢索資料,因為API對網站的資料有控制許可權。它還確保只有授權使用者可以與之互動。

API可以支援廣泛的資料格式,包括JSON,這使得與系統的互動變得很容易。

WordPress REST API是開發人員建立、更新或刪除資料的強大工具,此外還可以為網站建立自定義功能或與其他服務整合。此外,還有一些外掛可以擴充套件API的功能,如整合額外的認證方法。

什麼是React?

React是一個用於構建使用者介面的JavaScript庫。它是一個開源的、可重用的基於元件的前端庫,允許開發者使用宣告式語法構建使用者介面(UI)元件

React建立了一個互動式UI,並在資料變化時渲染元件。該庫在希望建立複雜的、可重複使用的元件的開發者中非常流行;有效地管理狀態;並容易實時更新使用者介面。

React強大的開發者社羣創造了一系列工具、庫和資源,以增強該庫的功能。許多組織和企業正在採用React作為他們的技術來構建複雜、動態和快速效能的網路應用。

使用React.js的熱門公司

使用React.js的熱門公司  (source: inexture.com)

為什麼使用React?

React提供了許多好處,使其成為開發複雜和動態網路應用的絕佳選擇。

以下是使用React的一些關鍵優勢:

  • 宣告式語法:React使用宣告式的方法來構建UI元件,使得建立可重用和高效的元件變得容易。
  • 大型社羣和生態系統:React有一個龐大而活躍的開發者社羣,這導致了一系列工具和庫的產生,以增強其功能。
  • 虛擬DOM:React使用虛擬DOM來實時更新UI。這意味著當狀態改變時,它只更新需要改變的元件,而不是重新渲染整個頁面。
  • 可重用性:React.js提供了可重複使用的元件,可以在不同的應用程式中使用,這大大減少了開發時間和精力。

如何用React建立一個無頭的WordPress網站

現在是時候讓我們動手了,學習如何用React建立和部署一個無頭WordPress網站。

請繼續閱讀,深入瞭解。

前提條件

在你開始學習本教程之前,請確保你有:

Step 1. 設定一個WordPress網站

讓我們從設定WordPress網站開始,因為這將作為React應用程式的資料來源。如果你已經設定了一個WordPress網站,你可以跳過這一部分;否則,就跟著做吧。

在本教程中,我們將使用DevKinsta,一個廣泛使用的快速、可靠的本地開發環境,用於建立、開發和部署WordPress網站。它的使用是完全免費的–只需從官方網站下載並安裝在你的系統上。

安裝完成後,開啟DevKinsta儀表板,點選New WordPress site,建立一個新的WordPress網站。

填寫所需的此類輸入,然後按Create site按鈕繼續。

DevKinsta網站建立頁面

DevKinsta網站建立頁面

這可能需要幾分鐘的時間,但一旦你的網站建立完畢,你就可以分別點選 “Open site” 或WP Admin選項來訪問它和它的管理面板。

接下來,為了啟用JSON API,你需要更新你網站的permalinks。

WordPress的管理面板上,點選設定,然後是固定連結。選擇文章名稱選項並點選儲存更改

WordPress固定連結設定

WordPress固定連結設定

你還可以使用Postman等工具來輕鬆地測試和傳送對WordPress REST API的請求。

Step 2: 設定一個React應用程式

現在我們已經建立了WordPress網站,我們可以開始在前臺工作了。如上所述,在本教程中,我們將使用React作為我們應用程式的前端。

為了開始工作,在你的終端執行下面的程式碼來建立一個React應用程式。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm create vite@latest my-blog-app
cd my-blog-app
npm install
npm create vite@latest my-blog-app cd my-blog-app npm install
npm create vite@latest my-blog-app 
cd my-blog-app 
npm install

上述命令將建立一個React應用程式,並安裝所需的依賴項。

我們還需要安裝Axios,一個用於發出HTTP請求的JavaScript庫。執行下面的命令來安裝它。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install axios
npm install axios
npm install axios

現在,為了啟動開發伺服器,你可以在終端執行 npm run dev 。然後伺服器應該在http://127.0.0.1:5173,初始化你的應用程式。

Vite + React登陸頁面

Vite + React登陸頁面

接下來,在你喜歡的程式碼編輯器中開啟你的專案,刪除任何你不需要的不必要的檔案,如assets資料夾、index.cssapp.css

你也可以用以下程式碼替換main.jsxApp.jsx裡面的程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
// main.jsx import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode>, )
// main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// App.jsx
import React from 'react'
export default function App() {
return (
<App />
)
}
// App.jsx import React from 'react' export default function App() { return ( <App /> ) }
// App.jsx
import React from 'react'
export default function App() {
return (
<App />
)
}

Step 3: 從WordPress取回文章

現在是時候從我們的WordPress網站上獲取文章了。

App.jsx中,新增以下狀態並從React匯入 useState

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const [posts, setPosts] = useState([])
const [posts, setPosts] = useState([])
const [posts, setPosts] = useState([])

useStateReact中的一個內建鉤子,用來給元件新增狀態,一個狀態指的是資料或屬性。

posts 用於從狀態中獲取資料, setPosts 用於向post新增新資料。我們也預設給state傳遞了一個空陣列。

接下來,在state後面新增以下程式碼,從WordPress REST API中獲取文章:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const fetchPosts = () => {
// Using axios to fetch the posts
axios
.get("http://headless-wordpress-website.local/wp-json/wp/v2/posts")
.then((res) => {
// Saving the data to state
setPosts(res.data);
});
}
// Calling the function on page load
useEffect(() => {
fetchPosts()
}, [])
const fetchPosts = () => { // Using axios to fetch the posts axios .get("http://headless-wordpress-website.local/wp-json/wp/v2/posts") .then((res) => { // Saving the data to state setPosts(res.data); }); } // Calling the function on page load useEffect(() => { fetchPosts() }, [])
const fetchPosts = () => {
// Using axios to fetch the posts
axios
.get("http://headless-wordpress-website.local/wp-json/wp/v2/posts")
.then((res) => {
// Saving the data to state
setPosts(res.data);
});
}
// Calling the function on page load
useEffect(() => {
fetchPosts()
}, [])

上面的程式碼是在頁面載入時執行 fetchPosts() 函式。在 fetchPosts() 函式中,我們使用Axios向WordPress API傳送一個 GET 請求,以檢索文章,然後儲存到我們先前宣告的狀態。

Step 4: 建立一個部落格元件

在根目錄中,建立一個名為components的新資料夾,並在其中建立兩個新檔案:blog.jsxblog.css

首先,在blog.jsx中新增以下程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import axios from "axios";
import React, { useEffect, useState } from "react";
import "./blog.css";
export default function Blog({ post }) {
const [featuredImage, setFeaturedimage] = useState();
const getImage = () => {
axios
.get(post?._links["wp:featuredmedia"][0]?.href)
.then((response) => {
setFeaturedimage(response.data.source_url);
});
};
useEffect(() => {
getImage();
}, []);
return (
<div class="container">
<div class="blog-container">
<p className="blog-date">
{new Date(Date.now()).toLocaleDateString("en-US", {
day: "numeric",
month: "long",
year: "numeric",
})}
</p>
<h2 className="blog-title">{post.title.rendered}</h2>
<p
className="blog-excerpt"
dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }}
/>
<img src={featuredImage} class="mask" />
</div>
</div>
);
}
import axios from "axios"; import React, { useEffect, useState } from "react"; import "./blog.css"; export default function Blog({ post }) { const [featuredImage, setFeaturedimage] = useState(); const getImage = () => { axios .get(post?._links["wp:featuredmedia"][0]?.href) .then((response) => { setFeaturedimage(response.data.source_url); }); }; useEffect(() => { getImage(); }, []); return ( <div class="container"> <div class="blog-container"> <p className="blog-date"> {new Date(Date.now()).toLocaleDateString("en-US", { day: "numeric", month: "long", year: "numeric", })} </p> <h2 className="blog-title">{post.title.rendered}</h2> <p className="blog-excerpt" dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} /> <img src={featuredImage} class="mask" /> </div> </div> ); }
import axios from "axios";
import React, { useEffect, useState } from "react";
import "./blog.css";
export default function Blog({ post }) {
const [featuredImage, setFeaturedimage] = useState();
const getImage = () => {
axios
.get(post?._links["wp:featuredmedia"][0]?.href)
.then((response) => {
setFeaturedimage(response.data.source_url);
});
};
useEffect(() => {
getImage();
}, []);
return (
<div class="container">
<div class="blog-container">
<p className="blog-date">
{new Date(Date.now()).toLocaleDateString("en-US", {
day: "numeric",
month: "long",
year: "numeric",
})}
</p>
<h2 className="blog-title">{post.title.rendered}</h2>
<p
className="blog-excerpt"
dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }}
/>
<img src={featuredImage} class="mask" />
</div>
</div>
);
}

在上面的程式碼中,我們建立了一個卡片元件,從WordPress的API中獲取包含博文資訊的 post 屬性。

getImage() 函式中,我們使用Axios來獲取特色圖片的URL,然後將該資訊儲存為狀態。

然後,我們新增了一個 useEffect 鉤子,一旦元件安裝完畢就呼叫 getImage() 函式。我們還新增了返回語句,在該語句中我們要渲染文章資料、標題、摘錄和圖片。

接下來,將下面的樣式新增到blog.css檔案中:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@import url("https://fonts.googleapis.com/css?family=Poppins");
.blog-container {
width: 400px;
height: 322px;
background: white;
border-radius: 10px;
box-shadow: 0px 20px 50px #d9dbdf;
-webkit-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
img {
width: 400px;
height: 210px;
object-fit: cover;
overflow: hidden;
z-index: 999;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.blog-title {
margin: auto;
text-align: left;
padding-left: 22px;
font-family: "Poppins";
font-size: 22px;
}
.blog-date {
text-align: justify;
padding-left: 22px;
padding-right: 22px;
font-family: "Poppins";
font-size: 12px;
color: #c8c8c8;
line-height: 18px;
padding-top: 10px;
}
.blog-excerpt {
text-align: justify;
padding-left: 22px;
padding-right: 22px;
font-family: "Poppins";
font-size: 12px;
color: #8a8a8a;
line-height: 18px;
margin-bottom: 13px;
}
@import url("https://fonts.googleapis.com/css?family=Poppins"); .blog-container { width: 400px; height: 322px; background: white; border-radius: 10px; box-shadow: 0px 20px 50px #d9dbdf; -webkit-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease; } img { width: 400px; height: 210px; object-fit: cover; overflow: hidden; z-index: 999; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; } .blog-title { margin: auto; text-align: left; padding-left: 22px; font-family: "Poppins"; font-size: 22px; } .blog-date { text-align: justify; padding-left: 22px; padding-right: 22px; font-family: "Poppins"; font-size: 12px; color: #c8c8c8; line-height: 18px; padding-top: 10px; } .blog-excerpt { text-align: justify; padding-left: 22px; padding-right: 22px; font-family: "Poppins"; font-size: 12px; color: #8a8a8a; line-height: 18px; margin-bottom: 13px; }
@import url("https://fonts.googleapis.com/css?family=Poppins");
.blog-container {
width: 400px;
height: 322px;
background: white;
border-radius: 10px;
box-shadow: 0px 20px 50px #d9dbdf;
-webkit-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
img {
width: 400px;
height: 210px;
object-fit: cover;
overflow: hidden;
z-index: 999;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.blog-title {
margin: auto;
text-align: left;
padding-left: 22px;
font-family: "Poppins";
font-size: 22px;
}
.blog-date {
text-align: justify;
padding-left: 22px;
padding-right: 22px;
font-family: "Poppins";
font-size: 12px;
color: #c8c8c8;
line-height: 18px;
padding-top: 10px;
}
.blog-excerpt {
text-align: justify;
padding-left: 22px;
padding-right: 22px;
font-family: "Poppins";
font-size: 12px;
color: #8a8a8a;
line-height: 18px;
margin-bottom: 13px;
}

然後,在App.jsx檔案中,在 return 語句中新增以下程式碼,以渲染部落格元件:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<div>
{posts.map((item) => (
<Blog post={item} />
))}
</div>;
<div> {posts.map((item) => ( <Blog post={item} /> ))} </div>;
<div>
{posts.map((item) => (
<Blog post={item} />
))}
</div>;

最後,這就是你的App.jsx應該有的樣子:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React, { useEffect, useState } from 'react'
import axios from "axios"
import Blog from './components/Blog';
export default function App() {
const [posts, setPosts] = useState([]);
const fetchPosts = () => {
axios
.get("http://my-awesome-website.local/wp-json/wp/v2/posts")
.then((res) => {
setPosts(res.data);
});
}
useEffect(() => {
fetchPosts()
}, [])
return (
<div>
{posts.map((item) => (
<Blog
post={item}
/>
))}
</div>
)
}
import React, { useEffect, useState } from 'react' import axios from "axios" import Blog from './components/Blog'; export default function App() { const [posts, setPosts] = useState([]); const fetchPosts = () => { axios .get("http://my-awesome-website.local/wp-json/wp/v2/posts") .then((res) => { setPosts(res.data); }); } useEffect(() => { fetchPosts() }, []) return ( <div> {posts.map((item) => ( <Blog post={item} /> ))} </div> ) }
import React, { useEffect, useState } from 'react'
import axios from "axios"
import Blog from './components/Blog';
export default function App() {
const [posts, setPosts] = useState([]);
const fetchPosts = () => {
axios
.get("http://my-awesome-website.local/wp-json/wp/v2/posts")
.then((res) => {
setPosts(res.data);
});
}
useEffect(() => {
fetchPosts()
}, [])
return (
<div>
{posts.map((item) => (
<Blog
post={item}
/>
))}
</div>
)
}

儲存檔案並重新整理你的瀏覽器標籤。現在你應該能夠看到你的部落格文章在頁面上呈現。

使用React.js的無頭WordPress

使用React.js的無頭WordPress

小結

無頭的WordPress為建立具有可擴充套件架構的快速表現的網站提供了一個很好的方法。隨著React和WordPress REST API的使用,以WordPress為內容管理系統建立動態和互動的網站比以往任何時候都容易。

上述教程主要講述的是利用React來建立無頭WordPress,但如果你希望使用Vue來實現,可以考慮我們另外一篇教程

評論留言