iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0
Modern Web

深入淺出,完整認識 Next.js 13 !系列 第 21

Day 21 - 功能性路由 ( 一 ):Route Group

  • 分享至 

  • xImage
  •  

昨天最後提到,Next 有提供幾個「功能性路由」,可以在不影響 URL 的前提下,享受 Next 針對提升路由開發體驗的機制。今天來分享第一個情境:


分類路由

有時候會因為協作需求,希望將幾個相同分類的 route segments 放進一個資料夾中,方便辨識。

舉例來說,我希望有個 /marketing ,用來放與行銷活動相關的 route segments,像是 /about, /blog 等等:

app/
├─ marketing/
│  ├─ about/
│  │  ├─ page.tsx
│  ├─ blog/
│  │  ├─ page.tsx

但因為我們在 /about/blog 父層加了一層 /marketing,/about 的 URL path 會變成 /marketing/about;/blog URL path 會改為 /marketing/blog。

假如我希望使用相同的資料夾結構,但 marketing 不要是一個 route segment 該怎麼辦?

這時候可以使用其中一個功能性路由 - Route Groups!

Route Groups

顧名思義,Route Groups 能讓開發者在不影響 URL 的前提下分類路由,呼應 App Router 提升專案架構彈性的理念。

使用方法很簡單,我們只需要在用一個小括號 () 包住資料夾名稱。以上述例子來說,我們只要將 /marketing 改為 /(marketing),marketing 就不會被判斷為一個 route segment。
route group
( 圖片來源:https://nextjs.org/docs/app/building-your-application/routing/route-groups )

除了透過路由分類,提升專案可維護性外,還有幾個常見的使用時機:

相同路由階層使用特殊檔案

從 URL 結構來看,因為 marketing 不是一個 route segment,/about 和 /blog 應屬同階層,但我們一樣可以在 /(marketing) 中使用 layout.tsxtemplate.tsx,來建立兩個路由共用的 layout。

比方說我們想讓 (/marketing) 中的 route segments 有個相同的 Header,就可以在 (/marketing) 中建一個 layout.tsx import Header:

/* app/(marketing)/layout.tsx */
import Header from './components/Header';

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <Header />
      {children}
    </>
  );
}

這樣當使用者進到 /about 和 /blog 都可以看到 <Header>

同理,我們也可以使用 loading.tsxerror.tsx 來定義共用的 streaming UI 和 error boundaries UI。

特定 Route Segement 不套用 Layout

因為只有在 route group 底下的 segments 才會吃到 route group 的 layout,而且 route group 不會影響到 URL,假如我們希望某個 route segment 底下 segment 不要套用 layout,也可以使用 route group 來達到效果。

舉例來說,我們希望 /dashboard 底下的 segments 可以有個相同的 Header,但唯獨 /dashboard/terms 不要有 Header,我們就可以將 layout.tsx 和需要 Header 的 segments 放進一個 route group 中,例如:

app/
├─ dashboard/
│  ├─ (withHeader)/
│  │  ├─ profile/
│  │  │  ├─ page.tsx
│  │  ├─ settings/
│  │  │  ├─ page.tsx
│  │  ├─ layout.tsx
│  ├─ terms/
│  │  ├─ page.tsx

這樣 /dashboard/profile 和 /dashboard/settings 會有 Header,但 /dashboard/terms 就不會有 Header。
https://ithelp.ithome.com.tw/upload/images/20230921/20161853hoKtls9oOP.png
https://ithelp.ithome.com.tw/upload/images/20230921/20161853QCWXJSvuWH.png

所以我們也可以透過 route group 來讓 layout 使用起來更加彈性。

建立不同的 Root Layout

Day 09 有提到,我們可以透過 route group 讓 root layout 不止一個。

假設我們今天希望將第一層 route segments 分為 marketing 和 shop 兩個分類,並且讓這兩個分類的 UI 和 UX 完全不同,我們就可以在 /app 根目錄創建 (/marketing) 和 (/shop) 兩個 route group,並在個別的 layout.tsx 中建立 root layout,來設定個別的 metadata、字型、<head><body>、全域共用的 components 等等。
route group root layouts
( 圖片來源:https://nextjs.org/docs/app/building-your-application/routing/route-groups )


最後總結一下,幾個常見可以使用 route groups 的情境:

  1. 想分類 route segments,但不想影響到 URL
  2. 想針對相同路由階層的 segments 使用 layout.tsxloading.tsxerror.tsx 等特殊檔案
  3. 想建立不同的 Root Layout,提供截然不同的 UI、UX

Route groups 也可以用來解決其中一個功能性路由的 bug,這部分就留到明天分享。以上就是 route group 的介紹,明天會再跟大家分享兩個功能性路由!

謝謝大家耐心的閱讀,我們明天見!


上一篇
Day 20 - Next.js 13 App Router 路由切換:<Link> & useRouter
下一篇
Day 22 - 功能性路由 ( 二 ):Parallel Routes & Intercepting Routes
系列文
深入淺出,完整認識 Next.js 13 !30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言