演示
工具演示頁面
什麼是 SSR?
Demo 頁面不是面向一般使用者的實用工具,而是一個用來驗證伺服器端渲染流程的小型參考頁。它展示 Next.js App Router 頁面如何在伺服器端取得資料,將結果直接渲染進首屏 HTML,同時載入目前語言的本地化文案。這個頁面適合檢查共用基礎設施是否正常:環境變數、伺服器端簽章請求、API 回傳結構、locale 路由與翻譯載入。它能正常運作,代表基礎 SSR 路徑大致健康,再排查複雜工具頁會更有方向;如果它失敗,問題通常在共用伺服器端設定或 API 連通性。Demo 頁應保持簡單,才能作為部署與框架改動後的煙霧測試。
使用方法
使用說明
- 頁面會自動於伺服器端呼叫後端 API
- HTML 已包含預先渲染的內容,無需使用者端額外請求
- 查看 API 回傳的資料
- 適用於需要 SEO 最佳化的頁面
開發注意事項
- 可將此頁面作為 SSR、語言包載入、簽章伺服器請求與 API 連線的基礎測試。
- 若此頁面失敗,請先檢查共用的伺服器配置,再除錯特定工具頁面。
使用場景
技術原理
本 Demo 頁面基於 Next.js 16 App Router 建置,預設使用伺服器端渲染(SSR)。當使用者請求頁面時,Node.js 伺服器先執行 React 元件,呼叫後端 API 取得資料,然後將完整渲染的 HTML 在單一回應中傳回瀏覽器。瀏覽器隨即開始解析和繪製 HTML,使用者在第一幀就能看到完整內容,無需等待 JavaScript 下載和執行。 這與傳統的使用者端渲染(CSR)形成鮮明對比。在 CSR 模式下,伺服器僅傳回一個近乎空白的 HTML 外殼和一個 JS 連結;瀏覽器必須下載 JS 套件、執行框架初始化、呼叫 API 取得資料,然後才能渲染頁面。從使用者角度來看就是「空白畫面等一陣子」,對搜尋引擎爬蟲來說更糟——大多數爬蟲不會執行 JavaScript,只會看到空白外殼。 SSR 之後,Next.js 還會注入一段 JavaScript 進行「hydration」:將現有的 DOM 與 React 元件樹關聯起來並綁定事件監聽器,使頁面變得可互動。完整流程為 HTML 解析 -> CSS 載入 -> JS 下載 -> hydrate -> 可互動。在三個 Core Web Vitals 中,LCP(最大內容繪製)和 CLS(累積版面配置偏移)在 SSR 下通常表現更好,而 INP(互動到下次繪製)則取決於 hydration 速度和事件處理器的實作品質。
- Next.js App Router:App Router 中的頁面預設為 Server Component,在伺服器上執行並自動傳回 HTML,無需額外設定。
- SSR vs CSR:SSR 以伺服器資源為代價提供快速首屏繪製和 SEO 友好性;CSR 適用於不需要 SEO 的內部儀表板和其他互動場景。
- 首屏繪製流程:HTML 解析 -> CSS 載入與渲染 -> JS 下載與執行 -> React hydrate -> 頁面可互動;每個步驟都會影響 LCP。
- SEO 爬蟲友好性:Googlebot 和 Bingbot 等主流爬蟲直接讀取 HTML 文字;SSR 輸出完整內容保證了爬取覆蓋率。
- Web Vitals 門檻:LCP < 2.5 秒、INP < 200 毫秒、CLS < 0.1 為 Google 建議的「良好」門檻;SSR 更容易達到 LCP 和 CLS。
- 簽章請求:Demo 頁面透過 serverApiFetch 在伺服器端呼叫後端 API,自動攜帶 X-Timestamp、X-Nonce 和 X-Sign 完成驗證。
範例
SSR(伺服器端渲染)
// app/page.tsx(預設為 Server Component)
export default async function Page() {
const data = await fetch('/api/info').then(r => r.json());
return <div>{data.title}</div>;
}
// HTML 已直接包含 <div>實際內容</div>CSR(客戶端渲染)
'use client';
import { useEffect, useState } from 'react';
export default function Page() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/info').then(r => r.json()).then(setData);
}, []);
return <div>{data?.title || 'Loading...'}</div>;
}
// 首次繪製的 HTML 只包含 <div>Loading...</div>首屏速度比較
# SSR
FCP: 0.4s LCP: 0.8s TTI: 1.2s
SEO: 爬蟲可直接取得完整內容
# CSR
FCP: 0.6s LCP: 1.8s TTI: 2.4s
SEO: 爬蟲必須執行 JS 才能取得內容常見問題
這個示範頁到底在示範什麼?
這是一個伺服器端渲染(SSR)的參考路由,展示 Next.js App Router 頁面如何在伺服器端取得資料、把結果嵌入第一份 HTML 回應,並仍能載入正確的本地化標籤。它不是給終端使用者用的工具 — 而是給開發者的冒煙測試。
資料是在伺服器端還是瀏覽器端取得?
伺服器端。頁面在 React Server Component 內呼叫 serverApiFetch(搭配 src/lib/sign.ts 的簽章請求標頭),瀏覽器收到的 HTML 已經包含資料。首次載入沒有客戶端的 fetch。
為什麼頁面有時會顯示舊資料?
Next.js 可能依 revalidate 設定快取 SSR 回應。若每次請求都需要新資料,請設定 'export const dynamic = "force-dynamic"' 或在 fetch 中傳入 {cache: 'no-store'}。示範路由使用預設行為,以保持範例簡潔。
我可以把這個模式套用到自己的頁面嗎?
可以 — 這正是它的用意。本路由示範如何將 next-intl 的 getTranslations 與伺服器端資料抓取結合,並把結果傳給 Client Component 進行互動。複製 layout.tsx 和 page.tsx,替換資料來源即可。
為什麼內部 API 還需要請求簽章?
X-Timestamp / X-Nonce / X-Sign 可以阻擋重放攻擊,並確保來自公網的請求確實來自受信任的客戶端。簽章金鑰對已登入使用者是 per-session,否則使用預設值;實作可參考 src/lib/sign.ts 與 src/lib/fetch.ts。
這個頁面會出現在生產建置中嗎?
它確實是部署應用的一部分作為參考用,但不會從首頁或工具列表連結,也不會作為使用者導向的工具宣傳。請把它當成以路由形式呈現的開發者文件。
想了解專案結構,我該從哪裡看起?
從本頁的 layout.tsx 和 page.tsx 開始,接著閱讀 src/i18n.ts(語言設定)、src/i18n/request.ts(全域翻譯載入)、src/lib/load-page-messages.ts(單頁翻譯)以及 src/lib/fetch.ts(簽章請求封裝)。