Day12 - Astro Series: Routes

Astro 系列文第十二日:基礎路由

一個漂亮的漸層背景上面有一句標題:「基礎路由」

前言

在上一章節介紹了基礎元件的使用,並且你也大概猜到了,只要元件放置在 src/pages/ 之內就會自動的成為 Astro 的頁面,在本章節會更細緻的介紹關於 Astro 的路由設置。

頁面路由

Astro 採用的路由策略被稱為「基於檔案的路由 File-based Routing」,所以可以透過整理 pages 內資料夾的結構來設定頁面。以下是支援的檔案種類:

  • .astro
  • .md
  • .mdx
  • .html
  • .js / .ts

靜態路由

每一個在 pages 中的文件都會成為對應的頁面,如下:

Terminal window
# 範例:靜態路由
src/pages/index.astro -> mysite.com/
src/pages/about.astro -> mysite.com/about
src/pages/about/index.astro -> mysite.com/about
src/pages/about/me.astro -> mysite.com/about/me
src/pages/posts/1.md -> mysite.com/posts/1

動態路由(SSG 模式)

單純的靜態路由可以滿足大多建構網頁的需求,但有時候會希望依照資料來創建對應的頁面,而非一個一個手動創建,這時候就是「動態路由」出場的時機,動態路由根據渲染模式,會有兩種不同的撰寫方式(SSG、SSR),本教學先著重介紹靜態生產頁面之模式。

舉例來說目前部落格有上百篇文章,不太可能特地為每一篇都創建一個頁面來生成路由,這麼做不但耗時也難以統一修改,但如果透過動態路由就可以根據資料來自動創建全新的路由。

由於在 SSG 模式下在建構時需要事先確定所有的路由,因此在動態路由元件中必須回傳一個 getStaticPaths 方法🔗,這個方法回傳一個陣列中夾帶著物件,物件中夾帶 params 屬性,並且可以選擇性的添加 props 屬性。

---
export async function getStaticPaths() {
return [
{ params: { /* 必要 */ }, props: { /* 選擇性添加 */ } },
{ params: { ... } },
{ params: { ... } },
// ...
];
}
---

至於元件檔案的名稱便是參數,回傳的 params 當中必須要有這個參數作為屬性。舉例來說:src/pages/authors/[author] 這個動態元件內可以這樣寫:

---
export async function getStaticPaths() {
return [
{ params: { author: 'mike' } },
{ params: { author: 'joe' } },
{ params: { author: 'mary' } },
// ...
];
}
const { author } = Astro.params;
---
<h1>這裡是 { author } 的頁面</h1>

就成功的生成三個頁面: /authors/mike/authors/joe/authors/mary 每個頁面中顯示對應的作者名稱,就完成最簡單的動態路由了,接著可以更進一步將資料抽離出來,使用 map 方法組成需要回傳的陣列:

// 第一步:在 pages/authors 資料夾內創建 [author].astro
---
export async function getStaticPaths() {
// 第二步:定義頁面資料
const pages = [
{
slug: 'mike',
author: "Mike",
description: "設計師",
},
{
slug: "joe",
author: "Joe",
description: "後端工程師",
},
{
slug: "mary",
author: "Mary",
description: "前端工程師",
},
];
// 第三步:使用 map 來組成 getStaticPaths 所要求的回傳格式
return pages.map(({ slug, author, description}) => {
return {
params: { author: slug },
props: { author, description },
};
});
}
// 第四步:在頁面中獲得傳入的 Props 並解構出來
const { author, description } = Astro.props;
---
// 第五步:在模板中顯示
作者: {author} - {description}

如此一來就成功的在 pages/authors 資料夾中創立了三位作者的頁面,並且顯示對應的資料。在這個範例中仍然是使用事先定義在元件中的資料 pages ,在未來章節中將會學到如何整合 CMS 或使用 Astro 內建的 Content Collection 來引入 .md 或 .mdx 檔案。

剩餘參數

如果需要更為靈活的頁面路徑可以嘗試使用剩餘參數 [...path] 在 .astro 檔案名稱上來匹配任何深度的路徑,舉例來說以下動態路由 pages/sequences/[...path].astro 將會產生三個頁面:

  1. /sequences/one/two/three
  2. /sequences/four
  3. /sequences

如果將參數設置為 undefined 則會匹配成頂級頁面,在這個案例中是 /sequences

---
export function getStaticPaths() {
return [
{params: {path: 'one/two/three'}},
{params: {path: 'four'}},
{params: {path: undefined }}
]
}
---

其他補充

404 頁面

如果要建構 404 錯誤頁面只需要在 /src/pages 裡面創建 404.astro404.md 即可。

排除頁面

Terminal window
src/pages/
├── _hidden-directory/
├── page1.md
└── page2.md
├── _hidden-page.astro
├── index.astro
└── posts/
├── _SomeComponent.astro
├── _utils.js
└── post1.md

如果希望暫時禁用頁面可以在檔案名稱添加下底線 _ 來避免該頁面被建構,像是以上例子只有 post1.mdindex.astro 會被渲染出來。

總結

在本章節介紹了如何創建 Astro 頁面,主要著重在 SSG 模式下靜態與動態路由如何建構,以及分頁與其他瑣碎的小功能介紹。

最後會建議實際動手練習:

延伸閱讀