Loading...
Loading...
Compare original and translation side by side
app/app/| File | Purpose |
|---|---|
| Unique UI for a route, makes route publicly accessible |
| Shared UI wrapper, preserves state across navigations |
| Loading UI using React Suspense |
| Error boundary for route segment |
| UI for 404 responses |
| Like layout but re-renders on navigation |
| Fallback for parallel routes |
| 文件 | 用途 |
|---|---|
| 为路由提供唯一UI,使路由可公开访问 |
| 共享UI包装器,在导航时保留状态 |
| 使用React Suspense实现的加载UI |
| 路由分段的错误边界 |
| 404响应的UI |
| 类似布局但在导航时重新渲染 |
| 并行路由的回退方案 |
| Pattern | Purpose | Example |
|---|---|---|
| Route segment | |
| Dynamic segment | |
| Catch-all segment | |
| Optional catch-all | |
| Route group (no URL) | |
| Named slot (parallel routes) | |
| Private folder (excluded) | |
| 模式 | 用途 | 示例 |
|---|---|---|
| 路由分段 | |
| 动态分段 | |
| 全捕获分段 | |
| 可选全捕获 | |
| 路由组(不影响URL) | |
| 命名插槽(并行路由) | |
| 私有文件夹(被排除) | |
page.tsxapp/
├── page.tsx # / (home)
├── about/
│ └── page.tsx # /about
└── blog/
├── page.tsx # /blog
└── [slug]/
└── page.tsx # /blog/:slugpage.tsxapp/
├── page.tsx # /(首页)
├── about/
│ └── page.tsx # /about
└── blog/
├── page.tsx # /blog
└── [slug]/
└── page.tsx # /blog/:slug// app/about/page.tsx
export default function AboutPage() {
return (
<main>
<h1>About Us</h1>
<p>Welcome to our company.</p>
</main>
)
}// app/about/page.tsx
export default function AboutPage() {
return (
<main>
<h1>关于我们</h1>
<p>欢迎来到我们的公司。</p>
</main>
)
}params// app/blog/[slug]/page.tsx
interface PageProps {
params: Promise<{ slug: string }>
}
export default async function BlogPost({ params }: PageProps) {
const { slug } = await params
const post = await getPost(slug)
return <article>{post.content}</article>
}params// app/blog/[slug]/page.tsx
interface PageProps {
params: Promise<{ slug: string }>
}
export default async function BlogPost({ params }: PageProps) {
const { slug } = await params
const post = await getPost(slug)
return <article>{post.content}</article>
}<html><body>// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}<html><body>// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="flex">
<Sidebar />
<main className="flex-1">{children}</main>
</div>
)
}// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="flex">
<Sidebar />
<main className="flex-1">{children}</main>
</div>
)
}// app/dashboard/loading.tsx
export default function Loading() {
return <div className="animate-pulse">Loading...</div>
}// app/dashboard/loading.tsx
export default function Loading() {
return <div className="animate-pulse">加载中...</div>
}// app/dashboard/error.tsx
'use client'
export default function Error({
error,
reset,
}: {
error: Error
reset: () => void
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
)
}// app/dashboard/error.tsx
'use client'
export default function Error({
error,
reset,
}: {
error: Error
reset: () => void
}) {
return (
<div>
<h2>出问题了!</h2>
<button onClick={reset}>重试</button>
</div>
)
}app/
├── (marketing)/
│ ├── layout.tsx # Marketing layout
│ ├── about/page.tsx # /about
│ └── contact/page.tsx # /contact
└── (shop)/
├── layout.tsx # Shop layout
└── products/page.tsx # /productsapp/
├── (marketing)/
│ ├── layout.tsx # 营销布局
│ ├── about/page.tsx # /about
│ └── contact/page.tsx # /contact
└── (shop)/
├── layout.tsx # 商城布局
└── products/page.tsx # /products// app/about/page.tsx
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About Us',
description: 'Learn more about our company',
}// app/about/page.tsx
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About Us',
description: 'Learn more about our company',
}// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { slug } = await params
const post = await getPost(slug)
return { title: post.title }
}// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { slug } = await params
const post = await getPost(slug)
return { title: post.title }
}_folder(folder)@slot(.)_folder(folder)@slot(.)references/routing-conventions.mdreferences/layouts-templates.mdreferences/loading-error-states.mdexamples/dynamic-routes.mdexamples/parallel-routes.mdreferences/routing-conventions.mdreferences/layouts-templates.mdreferences/loading-error-states.mdexamples/dynamic-routes.mdexamples/parallel-routes.md