---
# System prepended metadata

title: Next.js 概述
tags: [GDG 前端技術講座]

---

# Next.js 概述
<center><img src="https://images.prismic.io/techloset/Z1_3cpbqstJ98iN__a-complete-guide-to-next-js-a-react-js-framework.webp?auto=format%2Ccompress&fit=max&w=3840" /></center>

前言
---
「React 是一個非常出色的 **前端框架 (JavaScript Framework)**，它讓我們能用『元件 (Components)』來打造互動式的『客戶端 (Client-Side)』介面。

但是，當我們用 React 打造一個完整的『應用程式 (Application)』時，尤其是在生產環境 (Production)，我們會遇到幾個核心挑戰：

-   **SEO (搜尋引擎優化) 問題：** 傳統 React (CSR) 交付給瀏覽器的是一個幾乎空白的 HTML 和一包 JavaScript。搜尋引擎爬蟲可能只看到空白頁面，不利於網站排名。我們後續會講解 CSR 以及 **SSR (Next.js 的精隨)** 是甚麼。
    
-   **首屏載入效能 (Initial Load Performance)：** 使用者需要先下載完 JavaScript 檔案，然後在瀏覽器上執行 React，才能看到畫面。在網路較慢或設備效能較差時，使用者會面對一段時間的白畫面。
    
-   **架構的功能缺乏性：** 因為 React 這個框架本身只管 UI，所以我們需要自己決定如何處理：**路由 (Routing)**、**資料請求 (Data Fetching)**、**程式碼分片 (Code Splitting)**、**圖片優化**...等等。

**而 Next.js 就是為了解決這些問題而生的。**

但是這個框架它不是來取代 React 的，而是 React 的 **『生產環境框架 (Framework)』**。它在 React 之上，提供了一套完整、高效能的架構和『預設的最佳實踐 (Defaults and Conventions)』，讓我們能專注在業務邏輯，同時免費獲得 SSR、SSG 等強大功能。」

核心概念 (一) - 渲染模式 (Rendering Strategies) - 解決 SEO 與效能
---
### 四大渲染模式
-   **CSR (Client-Side Rendering)：** 傳統 React 渲染模式。Next.js 依然支援。
    - **客戶端渲染的比喻：**
        - IKEA 倉庫（伺服器）寄給你一個「包裹」。
        - 這個包裹就是**空白的 HTML** 和**一大包 JavaScript（零件和說明書）**。
        - 包裹本身不是椅子。你（客戶端瀏覽器）必須在你的客廳裡，自己打開包裹，看著說明書（執行 JS），花時間把椅子「組裝」起來（渲染出畫面）。
    -   **簡單總結：** 「先拿到一堆零件，然後自己忙半天才能用。」

-   **SSR (Server-Side Rendering)：** **每次請求 (Request) 都在伺服器上** 產生 HTML。
    -   **優點：** 對 SEO 友好、使用者能更快看到畫面、適合資料頻繁變動的頁面（例如：會員中心）。
    -   **伺服端渲染的比喻：**
        -   你打電話給木工師傅（伺服器），說：「我現在要一張椅子。」
        -   師傅 **「立刻」** 在他的工作室（伺服器）裡，為你量身打造這張椅子。
        -   完成後，他直接把一張 **「組裝好的完整椅子」**（HTML）運到你家。你一拿到就能立刻使用。
    -   **簡單總結：** 「向師傅下訂單 **（向伺服器請求）**，然後拿到客製化的成品 **（HTML）**。」每次下單，師傅都會重做一次。

-   **SSG (Static Site Generation)：** **在建構 (Build Time) 時就** 產生所有 HTML 頁面。
    
    -   **優點：** 速度最快（可被 CDN 緩存）、最安全、對 SEO 最好。適合內容不常變動的頁面（例如：部落格文章、行銷頁面）。
        
-   **ISR (Incremental Static Regeneration)：** SSG 的進化版。在背景「增量」重新產生靜態頁面，讓靜態網站也能擁有動態更新的資料。

### CSR (for React) v.s SSR (for Next.js) - Diagram
<center><img src="https://hackmd.io/_uploads/Hk4l_AlJWg.png" /></center>

核心概念 (二) - 路由系統 (Routing System) - 解決架構
---
在過去，頁面的路由上，無論是 Pages Router 還是 React Router，我們的思考都是『一個**檔案**對應一個**頁面**』。

> **Pages Router 範例：**
> 
> -   `pages/about.js` → 變成 `/about` 路由
>     
> -   `pages/dashboard.js` → 變成 `/dashboard` 路由

但在 App Router 中，這個思想改變了。 **核心轉變：『一個資料夾代表一個路由 (Route Segment)，裡面的 `page.js` 才是該路由的 UI。』**

> **App Router 範例：**
> 
> -   `app/about/page.js` → 變成 `/about` 路由
>     
> -   `app/dashboard/page.js` → 變成 `/dashboard` 路由

為什麼要這麼麻煩，多一層資料夾？因為這帶來了 App Router 最強大的功能... **巢狀佈局 (Nested Layout)**

### 巢狀佈局 (Nested Layout)
<center><img src="https://upload.wikimedia.org/wikipedia/commons/4/4a/%D0%9C%D0%B0%D1%82%D1%80%D1%91%D1%88%D0%BA%D0%B0-Russian_leaders_%E3%83%9E%E3%83%88%E3%83%AA%E3%83%A7%E3%83%BC%E3%82%B7%E3%82%AB_Shimada22.jpg" /></center>

巢狀佈局就好像是「俄羅斯娃娃」一樣，讓網頁變成一層一層嵌套的形式。

**請記住兩個最重要的特殊檔案：**
1. **`layout.js`：** 這就是 **『娃娃的殼』**。它是一個共享的 UI，負責包裹住在它內部的所有東西。
2. **`page.js`：** 這就是 **『娃娃的臉』** 。它是這個路由實際要顯示的、獨一無二的內容。


```
app/
├── layout.js       # 娃娃 1 (最大隻的娃娃) 的殼
│                   # (裡面放 <html>, <body>, Navbar, Footer)
│
├── page.js         # 娃娃 1 的臉 (首頁 /)
│
└── dashboard/
    │
    ├── layout.js   # 娃娃 2 (中間的娃娃) 的殼
    │               # (裡面放 Sidebar)
    │
    ├── page.js     # 娃娃 2 的臉 (儀表板首頁 /dashboard)
    │
    └── settings/
        │
        ├── layout.js # 娃娃 3 (最小的娃娃) 的殼
        │
        └── page.js # 娃娃 3 的臉 (設定頁 /dashboard/settings)
```
現在，我們來看當使用者瀏覽不同頁面時，Next.js 是怎麼『組裝』這些娃娃的：
* **當使用者去看首頁 (`/`)：**
    * Next.js 會拿 `app/page.js` (首頁的臉)
    * ...然後把它放進 `app/layout.js` (最大的殼) 裡。
    * **結果：** `[Navbar + [首頁內容] + Footer]`

* **當使用者去看儀表板首頁 (`/dashboard`)：**
    * Next.js 會拿 `app/dashboard/page.js` (儀表板的臉)
    * ...把它放進 `app/dashboard/layout.js` (帶有 Sidebar 的殼) 裡。
    * ...然後再把**整組**放進 `app/layout.js` (最大的殼) 裡。
    * **結果：** `[Navbar + [Sidebar + [儀表板內容]] + Footer]`

* **當使用者去看儀表板中的設定頁 (`/dashboard/settings`)：**
    * Next.js 會拿 `app/dashboard/settings/page.js` (設定頁的臉)
    * ...把它放進 `app/dashboard/layout.js` (Sidebar 的殼) 裡。**（注意：這裡沒有 `settings/layout.js`，所以它會自動找上一層的 `layout` 來用！）** 
    * ...最後再把**整組**放進 `app/layout.js` (最大的殼)。 
    * **結果：** `[Navbar + [Sidebar + [設定頁內容]] + Footer]`」

### 示意圖
<center><img src="https://hackmd.io/_uploads/HkVnDGc1Zl.png" /></center>

核心概念 (三) - API 路由 - 整合後端接口
---
Next.js 允許你直接在專案中建立後端 API。

* **如何運作：** 放在 `pages/api/` 或 `app/api/` 資料夾下的檔案，會成為一個 API 端點 (Endpoint)。 
* **優點：** 不需要額外架設一個 Node.js 伺服器。非常適合處理簡單的後端邏輯，例如：表單提交、連接資料庫、驗證...等。這就是所謂的 **BFF (Backend for Frontend)**。
<center><img src="https://hackmd.io/_uploads/BJlrDL7JWx.png" /></center>

核心概念 (四) - React Server Components (RSC)
---
* **Server Components (伺服器元件)：** 預設在 **伺服器端** 執行的元件。它們**不會**被下載到客戶端，JavaScript 體積 (Bundle Size) 為 0。
* **Client Components (客戶端元件)：** 傳統的 React 元件。需要互動 (如 `useState`, `onClick`) 的元件，必須加上 `"use client";` 標記。

光看以上對於這兩種 Component 的介紹可能不太懂。沒關係我們講得更清楚一些。

* **Server Components (伺服器元件)：** 就像是部落格的文章。當我們進入到部落格的文章頁面時，文章、作者、留言都會被加載，這些東西跟動作都是會透過 Server 去進行資料抓取，**使用者並不需要進行動作**，並且合成一個 HTML 檔案之後丟給客戶端，這些只需要靠 Server 就可以完成的物件，我們稱為 RSC。
* **Client Components (客戶端元件)：** 就像是部落格的留言區。你可以點讚、留言，這些動作不可能是由伺服器去幫你執行的，**而這些需要互動屬性的物件**，我們稱為 RCC 。

核心概念 (五) - 內建優化 (Built-in Optimizations)
---
Next.js 幫我們處理了很多麻煩的效能優化。

* **`<Image>` 元件：** 自動處理圖片優化（壓縮、轉檔 WebP）、響應式圖片、延遲載入 (Lazy Loading)。 
* **`<Link>` 元件：** 簡化前端路由，並自動在背景預先載入 (Prefetch) 連結頁面的資源，讓換頁體感極快。
* **字體優化 (`next/font`)：** 自動處理 Google Fonts 或本地字體，避免「字體閃爍 (FOUT)」和「版面位移 (Layout Shift)」。

---

文件參考：https://nextjs.org/docs












