為什麼你的 React 網站在 Google 搜尋裡找不到?
如果你曾經用純 React (Create React App 或 Vite) 寫過一個非常精美的官方網站,當你把它部署上線後,你興高采烈地去 Google 搜尋你的品牌名稱。 結果過了一個禮拜、一個月,你的網站在 Google 上依然是「查無此人」。
為什麼?因為傳統的 React 架構是一種叫做 CSR (Client-Side Rendering,客戶端渲染) 的技術。 當使用者打開你的網頁時,伺服器只會丟給他一個「空蕩蕩的白畫面 (空白的 HTML)」,以及一大包 JavaScript 程式碼。然後使用者的手機或電腦,必須要辛苦地去執行這包 JavaScript,才能把網頁的按鈕、圖片、文字給「畫 (Render)」出來。
這會造成兩個致命的問題:
- 載入極慢:如果客人的手機很舊,他可能要對著白畫面發呆 3 秒鐘,網頁才會跑出來。這 3 秒鐘足以讓他關掉網頁走人。
- SEO 災難:Google 的爬蟲機器人非常沒有耐心。當它爬到你的網站,看到一個空白的 HTML,它就會認為「這是一個沒有內容的垃圾網站」,然後轉身離開,你的網站排名就會掉到地心。
為了拯救這個災難,Next.js 誕生了。而它在最新的 App Router 版本中,帶來了一項革命性的武器:React Server Components (伺服器組件,簡稱 RSC)。
顛覆認知的魔法:在伺服器上就把網頁「畫好」
Server Components 的概念非常直觀:既然客人的手機跑得很慢,那我們為什麼不在「雲端伺服器 (Server)」上,先把網頁畫好,然後直接把「畫好的成品」丟給客人呢?
這就是 SSR (Server-Side Rendering) 與 RSC (Server Components) 的核心精神。
在 Next.js App Router 中,你寫的每一個 React 組件,預設都是 Server Component!
讓我們看一個實戰例子。假設這是一個顯示商品列表的頁面 (app/products/page.tsx):
// 🚨 注意!這是一個 Server Component。它是在 Vercel 的伺服器上執行的!
export default async function ProductsPage() {
// 因為在伺服器上,我們可以直接在這裡呼叫資料庫,完全不需要寫 API!
// 也不需要寫 useEffect 或 useState!
const res = await fetch('https://api.example.com/products');
const products = await res.json();
return (
<main>
<h1>我們的高級商品</h1>
<ul>
{products.map((product) => (
<li key={product.id}>{product.name} - ${product.price}</li>
))}
</ul>
</main>
);
}
這段程式碼看起來極度乾淨,沒有 useEffect、沒有 useState、沒有 isLoading 的轉圈圈判斷。
最神奇的是,當客人用手機連上這個網頁時,他瞬間就會看到所有商品。
而且,如果這時候你去檢視原始碼,你會發現所有的商品名稱都清清楚楚地寫在 HTML 裡面。Google 爬蟲一來,立刻就能看懂你在賣什麼,你的 SEO 排名就會一飛沖天!
那我們還需要 Client Components (客戶端組件) 嗎?
既然 Server Components 這麼強大,那我們乾脆全部的程式碼都用它不就好了嗎? 不行!
因為 Server Components 是在「伺服器上」畫完才送過來的,這意味著它沒有靈魂、不能互動。
如果你在 Server Component 裡面寫了一個按鈕 <button onClick={() => alert("嗨")}>,這在伺服器上是無效的,因為伺服器沒有滑鼠可以點擊。
凡是牽涉到以下三種情況,你就必須把該組件宣告為 Client Component (客戶端組件):
- 需要使用
onClick,onChange等使用者互動事件。 - 需要使用
useState,useEffect等 React 狀態生命週期。 - 需要使用瀏覽器專屬的 API (例如
window.localStorage)。
Vibe Prompt 實戰:教 AI 精準切割 Server 與 Client
在 Vibe Coding 時代,新手最常犯的錯就是把所有的程式碼都塞在一起,然後遇到 Next.js 報錯 Event handlers cannot be passed to Client Component props...。
這時候,你必須在 Prompt 裡面,教導 AI 使用「Client/Server 邊界切割」的戰術。
【Next.js 組件切割 Prompt】 我正在使用 Next.js App Router。我需要一個商品列表頁面,並且每個商品旁邊都有一個「加入購物車」的按鈕。 請幫我拆分成兩個檔案:
page.tsx(Server Component):負責用async/await fetch去抓取商品資料,並負責整體的 HTML 渲染與 SEO 優化。AddToCartButton.tsx(Client Component):這是一個獨立的按鈕組件,請在檔案第一行加上'use client'。當點擊時,請使用useState顯示一個「已加入」的動畫提示。- 請在
page.tsx中引入這個 Client Component 按鈕,實現完美的混合渲染架構。
透過這樣的詠唱,AI 會精準地幫你寫出:
- 重勞力、抓資料、顧 SEO 的事情:交給 Server Component 在雲端瞬間處理。
- 跟使用者互動、點擊動畫的事情:切出一小塊 Client Component,送到客人的手機上執行。
這就是現代 Web 開發的最高境界。你同時兼顧了「極致的載入速度 (SEO)」與「華麗的互動體驗」。 在下一章,我們將學習 Next.js 最令人聞風喪膽、但也最強大的黑魔法:Data Fetching (資料獲取) 與 Caching (快取策略)!
🎁 [VIP 專屬加碼] Next.js 企業級效能調校與接案話術
客戶花錢請你做網站,最在乎的往往只有兩件事:「網站跑得快不快?」 以及 「Google 搜尋能不能排在第一頁?」 這也是為什麼你必須精通 Next.js。在這個 Bonus 章節中,我們將教你如何把 Next.js 的效能發揮到極致,並把它變成你報價單上的黃金條款。
1. 終極武器:Next.js Image 元件 (next/image)
傳統網站載入慢,90% 的原因是因為圖片太大。
如果你在 Next.js 裡面使用傳統的 <img src="...">,Cursor 的 linter 會立刻給你一個警告。
你必須學會使用 Next.js 專屬的 <Image> 元件。
✅ Vibe Prompt 示範:
「請幫我把這個區塊的圖片改用
next/image元件。
- 請設定
layout="fill"與objectFit="cover"讓圖片響應式填滿容器。- 因為這是首頁的第一張大圖 (Hero Image),請加上
priority屬性,告訴瀏覽器優先載入這張圖,以提升 LCP 分數。」
只要加上 priority 這個字,你的網站在 Google 的 Core Web Vitals (核心網頁指標) 評分上就會大幅躍升。當你把這份滿分的報告截圖給客戶看時,他們會覺得這筆錢花得太值得了。
2. 靜態生成 (SSG) vs 伺服器渲染 (SSR) 的商業選擇
Next.js 有兩種渲染模式,身為架構師的你必須懂得幫客戶做選擇:
- SSG (Static Site Generation):在部署 (Build) 的時候就把網頁變成純 HTML。
- 適合場景:公司形象官網、部落格文章。
- 優點:速度極快 (因為不需要去資料庫抓資料),可以承受百萬流量不當機。
- SSR (Server-Side Rendering):每次使用者點擊時,伺服器才去抓最新資料畫出網頁。
- 適合場景:電商商品頁、股票報價、個人儀表板。
- 優點:資料永遠是最新的。
💡 接案談判話術: 你可以跟客戶說:「你們競爭對手的網站是用 WordPress 做的,只要同時有 1000 個人進站搶購,網站絕對當機。但我幫你用 Next.js 的 SSG 架構設計首頁,搭配 Vercel 的全球 CDN 邊緣節點。就算幾萬人同時進來,網站也一樣順暢,保證不會流失任何一張訂單。」 這就是把技術名詞,翻譯成老闆聽得懂的「賺錢語言」。
3. Vercel 部署隱藏地雷:環境變數 (Env Vars)
在將 Next.js 部署到 Vercel 時,最常發生的慘案就是「本機可以跑,上線全壞掉」。
這 100% 是因為你忘記在 Vercel 後台設定環境變數 (.env)。
請務必養成習慣:當你的專案使用了 Supabase 金鑰、綠界科技 API Key、或是 OpenAI 金鑰時。部署前,先去 Vercel 專案的 Settings > Environment Variables 把變數一個一個貼上去,然後才按下 Deploy。 守住這個細節,你就能確保每一次的專案上線都是完美的煙火秀!