This is a reference-style guide to the core conventions of the Next.js App Router.
File conventions
| File | Purpose |
|---|---|
layout.tsx | Shared UI that wraps a segment and its children |
page.tsx | The unique UI for a route, making it publicly accessible |
loading.tsx | Loading UI shown while a segment loads |
not-found.tsx | UI rendered when notFound() is called |
error.tsx | Error boundary for a segment |
route.ts | An API endpoint (Route Handler) for a segment |
Nested layouts
Layouts nest automatically based on folder structure. A layout.tsx in app/blog/ wraps every route under /blog, in addition to the root layout.
app/
layout.tsx → wraps everything
blog/
layout.tsx → wraps everything under /blog
page.tsx → /blog
[slug]/
page.tsx → /blog/[slug]
Static params for dynamic routes
For a fully static export, every dynamic segment needs generateStaticParams so Next.js knows every path to pre-render at build time.
export async function generateStaticParams() {
const posts = getAllPosts();
return posts.map((post) => ({ slug: post.slug }));
}Metadata
Each route can export a generateMetadata function to produce per-page <title>, description, and Open Graph tags at build time.
export async function generateMetadata({ params }) {
const { slug } = await params;
const post = getPostBySlug(slug);
return { title: post.title, description: post.description };
}Server vs. Client Components
By default, every component in app/ is a Server Component. Add "use client" at the top of a file only when you need interactivity, browser APIs, or React hooks like useState.