Photo by Hitesh Choudhary on Unsplash
Mastering Next.js: A Beginner's Guide to Effortless File-Based Routing
When it comes to building modern web applications, Next.js stands out for its simplicity and developer-friendly features. One of the core features that makes Next.js so powerful is its file-based routing system. Unlike traditional routing methods that rely on configuration files or extensive boilerplate, Next.js leverages the filesystem to automatically create routes. In this blog, we’ll break down file-based routing in Next.js and show you how to use it effectively.
In this article, we explore Next.js's file-based routing system, which simplifies the creation of web application routes by using the filesystem to define them automatically. We cover setting up a Next.js project, creating basic and dynamic routes, organizing structured folder hierarchies, implementing shared layouts, and defining API endpoints. The system enhances simplicity, dynamic routing, and SEO-friendly development, making it a powerful tool for building modern web applications.
What is File-Based Routing?
File-based routing means that the structure of your application’s routes is determined by the file and folder structure in the pages
or app
directory. Each file corresponds to a unique route in your application.
For example. under the app directory:
/app
page.jsx -> '/' (Homepage)
about/page.jsx -> '/about'
contact/page.jsx -> '/contact'
/app
page.tsx -> '/' (Homepage)
about/page.tsx -> '/about'
contact/page.tsx -> '/contact'
This eliminates the need for manually defining routes and allows you to focus on building features.
Setting Up Your Next.js Project
If you don’t have a Next.js project set up already, follow these steps:
Install Next.js using Create Next App:
npx create-next-app my-next-app cd my-next-app
Start the development server:
npm run dev
Open localhost:3000 in your browser. You should see the default Next.js homepage.
Creating Routes in Next.js
Basic Routes
To create a basic route:
Inside the
app
directory, create a folder namedabout
and then create a filepage.tsx
inside it:export default function About() { return <h1>About Page</h1>; }
Visit http://localhost:3000/about
in your browser. You’ll see the "About Page" content.
Combining Pages with a Common Layout
If you want to group routes like
about
,contact
, andother
under a commondashboard
structure with a shared layout i.e (dashboard) won’t be in routing, you can organize your files as follows:/app (dashboard) about page.tsx -> '/about' contact page.tsx -> '/contact' other page.tsx -> '/other' layout.tsx -> Common layout for all dashboard pages
Here’s how you can define the
layout.tsx
:export default function DashboardLayout({ children }) { return ( <div> <nav> <ul> <li><a href="/about">About</a></li> <li><a href="/contact">Contact</a></li> <li><a href="/other">Other</a></li> </ul> </nav> <main>{children}</main> </div> ); }
Each
page.tsx
file under theabout
,contact
, andother
folders can simply export the respective component, and they will automatically use thelayout.tsx
as their shared layout.
Organizing Routes with the App Directory
To better structure your application, you can organize files in the app
directory. Here’s an example of a structured folder hierarchy for a dashboard with shared layouts:
/app
(dashboard)
about
page.tsx -> '/dashboard/about'
contact
page.tsx -> '/dashboard/contact'
other
page.tsx -> '/dashboard/other'
layout.tsx -> Shared layout for all dashboard pages
(auth)
signin
page.tsx -> '/auth/signin'
signup
page.tsx -> '/auth/signup'
api
[[...route]]
route.ts -> API catch-all routes
accounts.ts -> Specific API route
Adding a Shared Layout for Dashboard Pages
Define a shared layout for all pages under (dashboard)
by creating a layout.tsx
file.
Creating API Routes
Next.js allows you to define API endpoints in the api
folder. Use [[...route]]
for catch-all routes or specific files for targeted endpoints.
Example: Catch-All API Route
// app/api/[[...route]]/route.ts
export async function GET(req) {
return new Response(JSON.stringify({ message: 'API Catch-All Route' }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
}
Example: Specific API Route
// app/api/accounts.ts
export async function GET(req) {
return new Response(JSON.stringify({ accounts: [] }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
}
Access these routes via http://localhost:3000/api/[[...route]]
or http://localhost:3000/api/accounts
.
Dynamic Routes
Dynamic routing allows you to capture dynamic values in the URL. To create a dynamic route, use square brackets ([]
) in the file name.
Example:
Create a file
/app/blog/[id].js
:import { useRouter } from 'next/navigation'; export default function BlogPost() { const router = useRouter(); const { id } = router.query; return <h1>Blog Post ID: {id}</h1>; }
Visit
http://localhost:3000/blog/123
. You’ll see "Blog Post ID: 123."
API Routes
Next.js also supports API routes, which let you create backend endpoints in the app/api
directory.
Example:
Create a file
/app/api/hello.js
:export default function handler(req, res) { res.status(200).json({ message: 'Hello, API!' }); }
Visit
http://localhost:3000/api/hello
. You’ll get a JSON response:{ "message": "Hello, API!" }
.
Catch-All Routes
Catch-all routes capture multiple segments of a URL. Use square brackets with three dots ([...]
).API Routes
Next.js also supports API routes, which let you create backend endpoints in the directory.
Example:
- Create a file:
export default function handler(req, res) {
res.status(200).json({ message: 'Hello, API!' });
}
- Visit . You’ll get a JSON response.
Example:
Create a file
/app/docs/[...slug].js
:import { useRouter } from 'next/navigation'; export default function Docs() { const router = useRouter(); const { slug } = router.query; return <h1>Docs Path: {slug?.join('/')}</h1>; }
Visit
http://localhost:3000/docs/guides/getting-started
. You’ll see "Docs Path: guides/getting-started."
Special Files in the app
Directory
_app.js
This file customizes the root component of your application and is useful for adding global styles or state management.
_document.js
This file is used to customize the HTML document structure, such as adding meta tags or external scripts.
_error.js
This file lets you customize the error page shown for 404 or other errors.
Advantages of File-Based Routing
Simplicity: Routes are auto-generated based on file structure.
Dynamic Routing: Easily handle dynamic segments without additional libraries.
API Integration: Backend and frontend live in the same project structure.
SEO-Friendly: Out-of-the-box support for server-side rendering and static site generation.
Conclusion
Next.js’s file-based routing is a game-changer for web development. It’s intuitive, powerful, and eliminates the need for complex routing configurations. By organizing your pages
or app
directory effectively, you can build scalable and maintainable applications with ease.
Start experimenting with your own routes and see how Next.js streamlines the development process. Happy coding!