One of Next.js's most powerful features is file-based routing. Instead of writing routing configuration, you simply create folders and files, and Next.js automatically creates routes for you. No setup, no config files, no route definitions—just an intuitive folder structure that maps directly to your URLs. Let's master this fundamental concept!
The Magic of File-Based Routing
In traditional web frameworks, you typically define routes in a configuration file or routing code:
// You write code like this:
app.get('/', homeHandler);
app.get('/about', aboutHandler);
app.get('/blog/:slug', blogPostHandler);
// Or configuration like this:
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/blog/:slug', component: BlogPost },
];With Next.js file-based routing, your file structure IS your routing:
File Structure → URL Routes
See how folders automatically become URL segments
📁 File Structure
app/ page.tsx
🌐 URL Path
/Root page.tsx creates the homepage at /
The Core Principle
Folders define route segments. Each folder in your app directory becomes a segment in the URL path.
page.tsx makes routes public. Only folders with a page.tsx file are accessible as routes.
Understanding Route Segments
A route is made up of segments separated by forward slashes:
URL: https://example.com/blog/posts/hello-world
Route segments:
/ ← Root
/blog ← First segment
/blog/posts ← Second segment
/blog/posts/hello-world ← Third segmentIn Next.js, each segment corresponds to a folder:
app/
blog/ ← /blog segment
posts/ ← /posts segment
hello-world/ ← /hello-world segment
page.tsx ← Makes /blog/posts/hello-world accessible📁 Folder = URL Segment
Think of each folder as adding a segment to your URL. The nesting of folders directly maps to the nesting of URL paths. It's that simple!
The Special page.tsx File
The page.tsx file is special. It has one job: make a route publicly accessible and define what users see at that route.
Without page.tsx
app/
products/ ← Folder exists but...
# No page.tsx!
Result: /products returns 404 (Not Found)With page.tsx
app/
products/
page.tsx ← Now it's a route!
Result: /products is accessibleWhat Goes in page.tsx
The page.tsx file exports a React component:
// This component renders at /products
export default function ProductsPage() {
return (
<div>
<h1>Our Products</h1>
<p>Browse our amazing product catalog!</p>
</div>
);
}Naming Requirements
- Must be named exactly
page.tsx(orpage.js) - Must be lowercase (not Page.tsx or pages.tsx)
- Must export a default component
- Can be a Server Component (default) or Client Component (with "use client")
Creating Your First Routes
Let's create some routes step by step in your Next.js project:
Step 1: Homepage (Already Exists)
Your project already has app/page.tsx which creates the homepage at /.
Step 2: Create an About Page
- Create a new folder:
app/about/ - Create
app/about/page.tsx - Add this code:
export default function AboutPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-4xl font-bold mb-4">About Us</h1>
<p className="text-lg text-gray-700">
Welcome to our company! We build amazing products with Next.js.
</p>
</div>
);
}Now visit http://localhost:3000/about in your browser. You'll see your about page!
Step 3: Create a Contact Page
- Create folder:
app/contact/ - Create file:
app/contact/page.tsx
export default function ContactPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-4xl font-bold mb-4">Contact Us</h1>
<p className="text-lg text-gray-700 mb-4">
Get in touch with our team!
</p>
<form className="space-y-4">
<input
type="text"
placeholder="Your name"
className="w-full px-4 py-2 border rounded"
/>
<input
type="email"
placeholder="Your email"
className="w-full px-4 py-2 border rounded"
/>
<button className="px-6 py-2 bg-blue-600 text-white rounded">
Send Message
</button>
</form>
</div>
);
}Visit http://localhost:3000/contact to see your contact page!
⚡ Instant Routes
Notice how you didn't need to configure anything, restart your server, or write routing code. Just create the folder and file, and the route exists instantly thanks to Fast Refresh!
Step 4: Create Nested Routes
Let's create a blog with nested routes:
app/
blog/
page.tsx ← /blog (blog home)
posts/
page.tsx ← /blog/posts (all posts)
first-post/
page.tsx ← /blog/posts/first-postCreate each file:
export default function BlogPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-4xl font-bold mb-4">Our Blog</h1>
<p>Welcome to our blog! Check out our latest posts.</p>
</div>
);
}export default function PostsPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-4xl font-bold mb-4">All Blog Posts</h1>
<ul className="space-y-2">
<li>Post 1</li>
<li>Post 2</li>
<li>Post 3</li>
</ul>
</div>
);
}export default function FirstPostPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-4xl font-bold mb-4">My First Blog Post</h1>
<p className="text-gray-700">
This is my first blog post. Welcome to my journey with Next.js!
</p>
</div>
);
}Now you have three working routes:
http://localhost:3000/bloghttp://localhost:3000/blog/postshttp://localhost:3000/blog/posts/first-post
Colocation: Keeping Related Files Together
Here's something powerful: you can put any file in your route folders. Only page.tsx (and other special files) affect routing.
app/
products/
page.tsx ← Route: /products
ProductCard.tsx ← Component (not a route)
ProductList.tsx ← Component (not a route)
utils.ts ← Utilities (not a route)
types.ts ← TypeScript types (not a route)
styles.module.css ← Styles (not a route)This is called colocation—keeping related code together. It makes your project more organized and easier to navigate.
Colocation Example
Notice how components and utilities live alongside page.tsx
Select a file or folder to see details
Only Special Files Create Routes
These are the only files that affect routing:
page.tsx- Creates a public routelayout.tsx- Creates shared layoutloading.tsx- Loading UIerror.tsx- Error UInot-found.tsx- 404 UIroute.ts- API endpoint
Everything else is ignored by the router!
Understanding Route Hierarchy
Routes form a hierarchy based on folder nesting:
app/ Root
├── page.tsx /
├── about/ About branch
│ └── page.tsx /about
└── blog/ Blog branch
├── page.tsx /blog
├── posts/ Posts sub-branch
│ ├── page.tsx /blog/posts
│ └── first/ First post sub-sub-branch
│ └── page.tsx /blog/posts/first
└── authors/ Authors sub-branch
└── page.tsx /blog/authorsThis hierarchy affects:
- Layouts: Parent layouts wrap child pages
- Loading states: Inherited down the tree
- Error boundaries: Catch errors in child routes
- Metadata: Can be overridden at each level
Private Folders (Optional Organization)
Sometimes you want folders for organization that don't create routes. Use an underscore prefix:
app/
_components/ ← Private folder (not a route)
Header.tsx
Footer.tsx
_lib/ ← Private folder (not a route)
utils.ts
api.ts
about/
page.tsx ← Public route: /aboutFolders starting with _ are completely ignored by the routing system. They're perfect for shared code that doesn't belong to any specific route.
📂 When to Use Private Folders
- Shared components used across many routes
- Utility functions and helpers
- Configuration or constants
- Test files
Index Routes (No Duplication Needed)
Unlike some frameworks, Next.js doesn't need index files. The page.tsx file in the folder itself serves as the index:
❌ Not Necessary (Other frameworks)
blog/
index.tsx ← Index file
posts/
index.tsx ← Index file✅ Next.js Way (Cleaner)
blog/
page.tsx ← Index for /blog
posts/
page.tsx ← Index for /blog/postsThis is cleaner and avoids confusion. page.tsx always means "the page at this route."
Common Routing Patterns
1. Landing Page + Sub-pages
app/
page.tsx → / (Homepage)
about/
page.tsx → /about
services/
page.tsx → /services
contact/
page.tsx → /contact2. Dashboard with Sections
app/
dashboard/
page.tsx → /dashboard (Overview)
analytics/
page.tsx → /dashboard/analytics
settings/
page.tsx → /dashboard/settings
users/
page.tsx → /dashboard/users3. Documentation Site
app/
docs/
page.tsx → /docs (Intro)
getting-started/
page.tsx → /docs/getting-started
api-reference/
page.tsx → /docs/api-reference
authentication/
page.tsx → /docs/api-reference/authentication4. E-commerce Structure
app/
page.tsx → / (Home)
products/
page.tsx → /products (All products)
featured/
page.tsx → /products/featured
categories/
electronics/
page.tsx → /products/categories/electronics
cart/
page.tsx → /cart
checkout/
page.tsx → /checkoutImportant Routing Rules
Rule 1: Folder Names Become URL Segments
Whatever you name your folder becomes part of the URL:
app/my-awesome-page/page.tsx→/my-awesome-pageapp/Products/page.tsx→/Products(case-sensitive!)
Rule 2: URLs are Case-Sensitive
/About and /about are different routes. Use lowercase for consistency.
Rule 3: Only One page.tsx Per Folder
You can't have multiple page.tsx files in the same folder. Each folder = one route.
Rule 4: Special Characters in Folder Names
Avoid special characters in folder names:
- ✅ Good:
my-page,user_profile,page123 - ❌ Bad:
my page(spaces),user@page,$special
Practice Exercise
Let's build a simple website structure. Create these routes in your Next.js project:
Challenge: Build a Portfolio Site
Create these pages:
- Homepage (
/) - Already exists - About page (
/about) - Projects page (
/projects) - Web projects (
/projects/web) - Mobile projects (
/projects/mobile) - Contact page (
/contact)
Solution Structure
app/
page.tsx ← Homepage
about/
page.tsx ← About
projects/
page.tsx ← Projects listing
web/
page.tsx ← Web projects
mobile/
page.tsx ← Mobile projects
contact/
page.tsx ← ContactStarter Code for Projects Page
import Link from 'next/link';
export default function ProjectsPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="text-4xl font-bold mb-6">My Projects</h1>
<p className="text-lg mb-8">
Check out my work in different categories:
</p>
<div className="grid md:grid-cols-2 gap-6">
<Link
href="/projects/web"
className="border rounded-lg p-6 hover:shadow-lg transition"
>
<h2 className="text-2xl font-semibold mb-2">Web Projects</h2>
<p>Explore my web development work</p>
</Link>
<Link
href="/projects/mobile"
className="border rounded-lg p-6 hover:shadow-lg transition"
>
<h2 className="text-2xl font-semibold mb-2">Mobile Projects</h2>
<p>Check out my mobile apps</p>
</Link>
</div>
</div>
);
}🎯 Try It Yourself
Pause here and actually create these files in your project! Navigate between the pages in your browser. The best way to learn is by doing!
Debugging Common Issues
Issue 1: 404 Not Found
Problem: Your route returns 404
Solutions:
- Check file name is exactly
page.tsx(lowercase) - Verify the folder structure matches your desired URL
- Make sure the file exports a default component
- Restart dev server if hot reload didn't catch the new file
Issue 2: Page Doesn't Update
Problem: Changes don't appear in browser
Solutions:
- Save the file (Ctrl+S / Cmd+S)
- Check terminal for errors
- Hard refresh browser (Ctrl+Shift+R / Cmd+Shift+R)
- Restart dev server
Issue 3: Wrong Route Created
Problem: Route appears at unexpected URL
Solutions:
- Check folder names - they determine the URL
- Remember URLs are case-sensitive
- Verify folder nesting matches desired URL structure
Key Takeaways
- Folders define route segments in your URL path
- page.tsx makes routes public - without it, folders are just for organization
- No configuration needed - routing is automatic based on file structure
- Colocation is encouraged - keep related files in route folders
- Private folders start with _ and are ignored by the router
- Nested folders create nested routes - the structure is intuitive
- Only special files affect routing - regular files are ignored
- Folder names become URL segments - name them descriptively
What's Next?
You now understand the fundamentals of file-based routing! You can create static routes by organizing folders and adding page.tsx files. But what about routes that need to be dynamic—like blog posts, user profiles, or product pages?
In the next lesson, we'll dive into creating pages with page.tsx in more detail, including how to structure your page components, use TypeScript types, and make your pages more sophisticated.
🚀 You're Making Great Progress!
File-based routing is one of Next.js's best features. Once you internalize this concept, building complex applications becomes incredibly intuitive. Keep practicing by creating different route structures!