File-Based Routing
In the Next.js App Router, routes are determined entirely by the folder structure inside app/: a folder represents a URL segment, and a page.tsx file inside that folder makes it a navigable route. There is no separate routing configuration file to maintain — creating app/about/page.tsx automatically creates the /about route, and nesting folders creates nested URL paths like app/blog/archive/page.tsx for /blog/archive.
Cricket analogy: Folders automatically becoming routes is like a stadium's physical stand numbering directly matching the ticket seating chart, so there's no separate mapping document needed between the ground layout and where fans sit.
Static and Dynamic Segments
Static segments are plain folder names like app/pricing/page.tsx for /pricing. Dynamic segments use square brackets, such as app/products/[id]/page.tsx, which matches /products/42 and exposes the value 42 via the params prop. Catch-all segments use [...slug] to match multiple path parts like /docs/a/b/c, and optional catch-all segments use double brackets [[...slug]] to also match the base route with zero extra parts.
Cricket analogy: A dynamic segment like [id] matching any product ID is like a jersey number that can be assigned to any player — the slot is fixed, but which specific player (value) fills it varies each match.
// File tree:
// app/
// page.tsx -> "/"
// about/page.tsx -> "/about"
// products/[id]/page.tsx -> "/products/42"
// docs/[...slug]/page.tsx -> "/docs/a/b/c"
// app/products/[id]/page.tsx
export default async function ProductPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const product = await fetch(`https://api.example.com/products/${id}`).then(r => r.json());
return <div><h1>{product.name}</h1><p>${product.price}</p></div>;
}Route Groups and Special Files
Route groups let you organize folders without affecting the URL by wrapping a folder name in parentheses, such as app/(marketing)/about/page.tsx, which still resolves to /about — the (marketing) segment is purely organizational, useful for applying a distinct layout to a group of routes. Special files within any route folder automatically create behavior: loading.tsx shows a loading UI during data fetching, error.tsx catches runtime errors, and not-found.tsx renders for unmatched routes or a called notFound() function.
Cricket analogy: Route groups organizing folders without affecting the URL are like grouping players into batting order categories (openers, middle order) internally for team meetings, without that grouping ever appearing on the actual scorecard.
Parallel routes ([@slot](...)) and intercepting routes ((.)folder) are more advanced App Router features that let you render multiple independent pages in the same layout simultaneously, or show a route as a modal while preserving the underlying page — useful patterns for things like Instagram-style photo modals.
Linking Between Routes
Navigation between routes should use the next/link component rather than a plain HTML anchor tag. Link automatically prefetches the linked route's code and data when it scrolls into the viewport (in production), and performs client-side navigation that updates the URL and page content without a full browser reload, preserving shared layout state like a persistent navbar.
Cricket analogy: Link's automatic prefetching is like a fielder anticipating where the ball will go and pre-positioning themselves before the shot is even played, rather than reacting only after the ball leaves the bat.
Using a plain <a href="/about"> instead of next/link for internal navigation causes a full page reload, discarding client-side state, losing the performance benefit of prefetching, and re-downloading shared assets unnecessarily. Reserve plain anchor tags for external links.
- Folders inside app/ automatically become URL segments; page.tsx makes a folder a navigable route.
- Dynamic segments use [param], catch-all segments use [...slug], optional catch-all uses [[...slug]].
- Route groups in parentheses like (marketing) organize folders without affecting the URL.
- Special files loading.tsx, error.tsx, and not-found.tsx provide automatic UI boundaries.
- next/link enables client-side navigation with automatic prefetching.
- Plain <a> tags cause full page reloads and should be reserved for external links.
- Parallel and intercepting routes are advanced patterns for modals and simultaneous views.
Practice what you learned
1. What makes a folder inside app/ a publicly navigable route?
2. Which folder naming convention creates a dynamic route segment?
3. What is the purpose of a route group like app/(marketing)/about/page.tsx?
4. What happens when you use a plain <a> tag instead of next/link for internal navigation?
5. Which special file renders automatically when a route's data is still being fetched?
Was this page helpful?
You May Also Like
The App Router vs Pages Router
A comparison of Next.js's two routing systems — the legacy Pages Router and the modern App Router built on React Server Components.
Layouts and Nested Routes
How layout.tsx files in the Next.js App Router share UI across routes, compose through nesting, and persist state across navigations.
Creating a Next.js Project
How to scaffold a new Next.js application with create-next-app, understand its generated project structure, and run the development server.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics