Next.js routing uses folders inside the app/ directory to define URL paths without a central router config file. Every folder represents a URL segment, and a page.tsx file inside that folder makes the route reachable in a browser.
If a folder does not contain a page.tsx file, users cannot visit that path directly. This lets you keep helper components or styles close to a route safely.
flowchart TD
app["app/"] --> home["page.tsx -> /"]
app --> about["about/"]
about --> aboutPage["page.tsx -> /about"]
app --> blog["blog/"]
blog --> slug["[slug]/"]
slug --> slugPage["page.tsx -> /blog/:slug"]
To create a static URL like /pricing or /dashboard/settings, create matching nested folders inside app/ and add a page.tsx file to each endpoint.
| File Path | Browser URL |
|---|---|
app/page.tsx |
/ |
app/pricing/page.tsx |
/pricing |
app/dashboard/settings/page.tsx |
/dashboard/settings |
Dynamic routes match changing URL values such as blog slugs, product IDs, or user handles. Wrap the folder name in square brackets, like [slug], and await params inside your async Server Component.
// app/blog/[slug]/page.tsx
interface BlogPageProps {
params: Promise<{ slug: string }>;
}
export default async function BlogPostPage({ params }: BlogPageProps) {
const { slug } = await params;
return (
<article className="max-w-3xl mx-auto p-6">
<h2 className="text-2xl font-bold capitalize">{slug.replaceAll('-', ' ')}</h2>
<p className="mt-3 text-gray-600">Loaded dynamic route for slug: {slug}</p>
</article>
);
}
Route groups let you split routes into logical areas without changing the public URL. Wrap a folder name in parentheses, such as (marketing) or (account), and Next.js omits that folder name from the URL path.
app/
├── (marketing)/
│ ├── layout.tsx
│ ├── about/page.tsx -> /about
│ └── pricing/page.tsx -> /pricing
└── (account)/
├── layout.tsx
└── profile/page.tsx -> /profile
await params in Next.js 15+: Dynamic params is a Promise in modern App Router pages, so read it with await params.page.tsx inside app/about/, not app/about.tsx.app/ has no page.tsx file?The folder does not expose a public URL route. You can safely store local components, types, or test files inside it.
Use [...slug] in a folder name to match multiple nested segments, such as /docs/auth/tokens, as an array of strings.
Route groups let different sections use separate layout.tsx shells while keeping clean, short public URLs.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With