跳到內容
App Router開始使用版面配置與頁面

如何建立版面配置與頁面

Next.js 使用檔案系統基礎路由,代表你可以使用資料夾和檔案來定義路由。本頁面將引導你瞭解如何建立版面配置和頁面,以及它們之間的連結。

建立頁面

頁面是在特定路由上渲染的 UI。若要建立頁面,請在 app 目錄中新增 page 檔案,並預設匯出 React 元件。例如,若要建立首頁 (/)

page.js special file
app/page.tsx
export default function Page() {
  return <h1>Hello Next.js!</h1>
}

建立版面配置

版面配置是在多個頁面之間共用的 UI。在導航時,版面配置會保留狀態、保持互動性,且不會重新渲染。

你可以從 layout 檔案預設匯出 React 元件來定義版面配置。元件應接受 children prop,其可以是頁面或另一個 版面配置

例如,若要建立接受你的首頁作為子項的版面配置,請在 app 目錄中新增 layout 檔案

layout.js special file
app/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        {/* Layout UI */}
        {/* Place children where you want to render a page or nested layout */}
        <main>{children}</main>
      </body>
    </html>
  )
}

上面的版面配置稱為 根版面配置,因為它定義在 app 目錄的根目錄。根版面配置是必要的,且必須包含 htmlbody 標籤。

建立巢狀路由

巢狀路由是由多個 URL 片段組成的路由。例如,/blog/[slug] 路由由三個片段組成

  • / (根片段)
  • blog (片段)
  • [slug] (葉片段)

在 Next.js 中

  • 資料夾用於定義對應到 URL 片段的路由片段。
  • 檔案 (例如 pagelayout) 用於建立在片段中顯示的 UI。

若要建立巢狀路由,你可以將資料夾互相巢狀放置。例如,若要為 /blog 新增路由,請在 app 目錄中建立名為 blog 的資料夾。然後,若要讓 /blog 可以公開存取,請新增 page 檔案

File hierarchy showing blog folder and a page.js file
app/blog/page.tsx
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'
 
export default async function Page() {
  const posts = await getPosts()
 
  return (
    <ul>
      {posts.map((post) => (
        <Post key={post.id} post={post} />
      ))}
    </ul>
  )
}

你可以繼續巢狀放置資料夾以建立巢狀路由。例如,若要為特定部落格文章建立路由,請在 blog 內建立新的 [slug] 資料夾並新增 page 檔案

File hierarchy showing blog folder with a nested slug folder and a page.js file
app/blog/[slug]/page.tsx
function generateStaticParams() {}
 
export default function Page() {
  return <h1>Hello, Blog Post Page!</h1>
}

小提示:將資料夾名稱包在方括號中 (例如 [slug]) 會建立特殊的 動態路由片段,用於從資料產生多個頁面。這對於部落格文章、產品頁面等非常有用。

巢狀版面配置

預設情況下,資料夾階層中的版面配置也是巢狀的,這表示它們會透過其 children prop 包裝子版面配置。你可以透過在特定路由片段 (資料夾) 內新增 layout 來巢狀放置版面配置。

例如,若要為 /blog 路由建立版面配置,請在 blog 資料夾內新增 layout 檔案。

File hierarchy showing root layout wrapping the blog layout
app/blog/layout.tsx
export default function BlogLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}

如果你要組合以上兩個版面配置,根版面配置 (app/layout.js) 會包裝部落格版面配置 (app/blog/layout.js),而部落格版面配置又會包裝部落格 (app/blog/page.js) 和部落格文章頁面 (app/blog/[slug]/page.js)。

頁面之間連結

你可以使用 <Link> 元件 在路由之間導航。<Link> 是內建的 Next.js 元件,它擴充了 HTML <a> 標籤,以提供預先載入和用戶端導航。

例如,若要產生部落格文章清單,請從 next/link 匯入 <Link>,並將 href prop 傳遞給元件

app/ui/post.tsx
import Link from 'next/link'
 
export default async function Post({ post }) {
  const posts = await getPosts()
 
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.slug}>
          <Link href={`/blog/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  )
}

<Link> 是在你的 Next.js 應用程式中路由之間導航的主要和建議方式。然而,你也可以使用 useRouter hook 進行更進階的導航。