Next.js 以 頁面的概念 打造出基於檔案系統( file-system )的路由功能。
當一個檔案被加進 pages
資料夾,它會自動地變成可用的路由。
這些被加入 pages
資料夾的檔案被用來定義最常見的模式。
路由器會自動地將命名為 index
的檔案作為資料夾根目錄的頁面。
pages/index.js
→ /
pages/blog/index.js
→ /blog
路由器支援巢狀檔案。如果你建立了一個巢狀的資料夾結構,檔案仍然會依照相同的方式自動地配置路由。
pages/blog/first-post.js
→ /blog/first-post
pages/dashboard/settings/username.js
→ /dashboard/settings/username
如果要匹配一個動態路由片段,你可以使用中括號。這可以使其與參數名稱相匹配。
pages/blog/[slug].js
→ /blog/:slug
(/blog/hello-world
)pages/[username]/settings.js
→ /:username/settings
(/foo/settings
)pages/post/[...all].js
→ /post/*
(/post/2020/id/title
)查看 Dynamic Routes documentation 頁面可以學習更多動態路由如何運作。
Next.js 的路由允許你使用客戶端路由來跳轉頁面,相似於單頁式應用程式( single-page application )。
一個稱作 Link
的 React 元件可以供你用來作為客戶端的路由跳轉。
import Link from 'next/link' function Home() { return ( <ul> <li> <Link href="/"> <a>Home</a> </Link> </li> <li> <Link href="/about"> <a>About Us</a> </Link> </li> <li> <Link href="/blog/hello-world"> <a>Blog Post</a> </Link> </li> </ul> ) } export default Home
上面的例子用了多個連結,每個連結都對應著一個已知頁面的路徑(href
):
/
→ pages/index.js
/about
→ pages/about.js
/blog/hello-world
→ pages/blog/[slug].js
任何出現在畫面中的 <Link />
元件(包含頁面初始化或後續使用者向下捲動頁面)如果指向使用了 靜態生成 ,將會被提前載入(包含該頁面所需的資料)。使用 伺服器端渲染 的頁面 不會 提前載入。
你也可以使用插入變數的方式來建立一個路徑,這時 動態路由片段 可以派得上用場。舉例來說,顯示一個已經被當成 props 傳入元件的文章清單。
import Link from 'next/link' function Posts({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> <Link href={`/blog/${encodeURIComponent(post.slug)}`}> <a>{post.title}</a> </Link> </li> ))} </ul> ) } export default Posts
在以下範例中使用了
encodeURIComponent
來確保路徑可以兼容 utf-8 編碼格式。
或者,使用 URL 物件( URL Object ):
import Link from 'next/link' function Posts({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> <Link href={{ pathname: '/blog/[slug]', query: { slug: post.slug }, }} > <a>{post.title}</a> </Link> </li> ))} </ul> ) } export default Posts
現在我們使用 URL 物件來建立路徑,而不是使用插入變數的方式:
pathname
是 pages
資料夾裡的頁面名稱。如同 /blog/[slug]
這個例子一樣。query
是一個有著動態片段的物件。如同 slug
這個例子一樣。在 React 的元件中,你可以使用 useRouter
或者 withRouter
來存取 router
物件。
一般來說,我們建議使用 useRouter
。
路由器被分成許多的部分: