Next.js Intercepting Routes
Last Updated :
12 Aug, 2024
Next.js is the most widely used React framework. With each new major release, the Next.js team is adding amazing features to the framework. Here, We will deep dive into a feature called Intercepting Routes which was added in a recent release to render modal on the same page with a unique URL.
Intercepting routes involves using a special lifecycle method provided by the framework to execute code before navigating to a different page. This can be useful for tasks like authentication, data fetching, or logging.\
Prerequisites
Parallel Routes in Next.js
Knowledge of parallel routes is important to effectively use intercepting routes. Parallel routes allow you to render one or more pages in the same layout simultaneously or conditionally.
Parallel routes are defined using slots. To create a slot, name your folder with a @
prefix. For example, using @news
in your folder structure creates a slot that can receive props from the shared parent layout. In this case, the root layout acts as the parent layout.
Here’s how you can modify the layout.tsx
file to integrate the slot:
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
news,
}: Readonly<{
children: React.ReactNode;
news: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
{news}
{children}
</body>
</html>
);
}
What is default.{jsx | tsx} file?
By default, Next.js keeps track of the active state (or subpage) for each slot. During client-side navigation, Next.js will perform a partial render, changing the subpage within the slot, while maintaining the other slot's active subpages, even if they don't match the current URL. But after browser refresh, Next.js cannot determine the active state for the slots that don't match the current URL. Instead, it will render a default.js file for the unmatched slots, or 404 if default.js doesn't exist.
Intercepting Routes in Next.js
Intercepting routes allows to load of content of another route in current page. Combined with Next.js parallel routes, this is can be used to display modal over current page to show contents of another page.
Example: Clicking an image or button might open a modal on top of the current page. When accessed via a URL or after a hard refresh, it routes to a dedicated page.
We are going to make a similar application where clicking over login button will open a modal. But when accessed using URL, it will open the login page.
Convention for Intercepting routes
Intercepting routes works similar to relative paths. Intercepting routes are defined using (..) convention.
You can use:
- (.) to match segments on the same level
- (..) to match segments one level above
- (..)(..) to match segments two levels above
- (...) to match segments from the root app directory
Important Note:
Although the (..)
convention may resemble relative paths, it differs significantly. The (..)
convention is based on route segments rather than the file system. Each folder in a route represents a route segment, which maps to a corresponding segment in the URL path. Note that parallel routes are not considered route segments because they use slots, which do not affect the URL.
Steps To Implement Next.js Intercepting Routes
Step 1: Copy one of the following command to initialise the the application in your desired directory.
#npm
npx create-next-app@latest
#yarn
yarn create next-app
#pnpm
pnpm create next-app
Options:
Next.js optionsStep 2: Install shadcn ui library.
To install the Shadcn UI library, use one of the following commands based on your package manager:
#npm
npx shadcn-ui@latest init
#yarn
yarn dlx shadcn-ui@latest init
#pnpm
pnpm dlx shadcn-ui@latest init
Shadcn choicesStep 3: Add the following components.
To add the required components, use one of the following commands based on your package manager:
#npm
npx shadcn-ui@latest add button card dialog input label
#yarn
yarn dlx shadcn-ui@latest add button card dialog input label
#pnpm
pnpm dlx shadcn-ui@latest add button card dialog input label
Step 4: Start the Development Server
#npm
npm run start
#yarn
yarn dev
#pnpm
pnpm dev
Dependencies
"dependencies": {
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"lucide-react": "^0.403.0",
"next": "14.2.4",
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.4",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
Folder Structure
Folder StructureWe going to make simple application where if user clicks on the login button in home page then a modal will open. But if browser is refreshed or accessed to URL, login page will open.
JavaScript
JavaScript//components/login-form.tsx
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
export function LoginForm() {
return (
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle className="text-2xl">Login</CardTitle>
<CardDescription>
Enter your email below to login to your account.
</CardDescription>
</CardHeader>
<CardContent className="grid gap-4">
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="[email protected]" required />
</div>
<div className="grid gap-2">
<Label htmlFor="password">Password</Label>
<Input id="password" type="password" required />
</div>
</CardContent>
<CardFooter>
<Button className="w-full">Sign in</Button>
</CardFooter>
</Card>
);
}
Step 2: Create login route in root directory. Here is the code for page.tsx.
JavaScript
//app/login/page.tsx
import { LoginForm } from "@/components/login-form";
export default function Page() {
return (
<main className="w-full h-screen flex
flex-col justify-center items-center gap-7">
<h1 className="text-4xl font-semibold ">Login page</h1>
<LoginForm />
</main>
);
}
Step 3: Create a parallel is same level as root layout and name it @modal.
Step 4: Modify the root layout.tsx to add the slot for parallel route.
JavaScript
//app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
modal,
}: Readonly<{
children: React.ReactNode;
modal: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
{modal}
{children}
</body>
</html>
);
}
Step 5: Create required files.
Inside the @modal directory, create (.)login directory and inside that, create page.tsx file. When /login route will be access through next/link component, it will show a modal. Here is the code for modal and page.tsx.
JavaScript
//app/@modal/(.)login/page.tsx
import { LoginForm } from "@/components/login-form";
import { Modal } from "@/components/modal";
export default function Page() {
return (
<Modal>
<LoginForm />
</Modal>
);
}
JavaScript
//components/modal.tsx
"use client";
import { useRouter } from "next/navigation";
import { Dialog, DialogContent, DialogOverlay } from "./ui/dialog";
export function Modal({ children }: { children: React.ReactNode }) {
const router = useRouter();
return (
<Dialog defaultOpen={true} open={true}
onOpenChange={() => router.back()}>
<DialogOverlay>
<DialogContent className="w-fit py-9 px-7">
{children}</DialogContent>
</DialogOverlay>
</Dialog>
);
}
Step 6: Create default.tsx folder
Create default.tsx inside the (.)login directory. It does nothing and only added because Next.js requires it. Otherwise Next.js will render a 404 page.
JavaScript
//app/@modal/default.tsx
export default function Default() {
return null;
}
Step 7: At last, modify the root page.tsx. Clicking on the link link component will open the modal.
JavaScript
//app/page.tsx
import Link from "next/link";
export default function Home() {
return (
<main className="w-full h-screen flex flex-col items-center gap-7 p-20">
<h1 className="text-3xl font-semibold">Home page</h1>
<Link
href="/login"
className="bg-black text-white px-4 py-2 font-semibold rounded-sm"
>
Login
</Link>
</main>
);
}
Now our project is completely ready and should work properly. Restart the dev server otherwise it will not work. This is a bug present in Next.js version 14.2.3.
Output
Similar Reads
Next.js Injecting the router
In this article, we will learn how we can inject the router into our NextJS project. NextJS is a React-based framework. It has the power to Develop beautiful Web applications for different platforms like Windows, Linux, and mac. Next.js has a file-system-based router built on the concept of pages. W
3 min read
useRouter in Next JS
Next.js is a React framework that is used to build full-stack web applications. It is used both for front-end as well and back-end. It comes with a powerful set of features to simplify the development of React applications. One of its features is useRouter hook that is part of the Next.js routing sy
4 min read
Next JS Dynamic API Routes
Next.js dynamic API routes allow you to create flexible endpoints that can handle various parameters, enabling powerful and versatile server-side functionalities within your application.Prerequisites:JavaScript and React JS basicsFamiliar with Next JSRestful API's conceptDynamic API RoutesDynamic AP
2 min read
Next.js Introduction
Next.js is a powerful and flexible React framework that has quickly become popular among developers for building server-side rendered and static web applications. Created by Vercel, Next.js simplifies the process of developing modern web applications with its robust feature set. In this article, weâ
5 min read
Next JS Routing: Internationalization
Next.js allows you to configure routing and rendering for multiple languages, supporting both translated content and internationalized routes. This setup ensures your site adapts to different locales, providing a seamless and localized experience for users across various languages.Prerequisites:NPM
4 min read
How To Get Current Route In Next.js?
Next.js is a popular React framework that makes it easy to build server-side rendered and static web applications. One common task in web development is determining the current route or URL of the page. In Next.js, this can be done using the built-in useRouter hook. This article will guide you throu
3 min read
Route Segment Config Next.js
Next.js, a popular React framework, continues to evolve, adding features that enhance web application efficiency and scalability. One such feature is Route Segment Config, providing control over route handling and configuration.What is Route Segment Config?Route Segment Config allows developers to d
4 min read
Next.js Functions: NextRequest
In Next.js, particularly with the introduction of Next.js 13 and the new App Router, NextRequest is part of the API used in the new routing system. It is designed to provide a simple and more powerful way to handle HTTP requests within Next.js applications, especially in API routes and middleware fu
5 min read
Next JS File Conventions: route.js
In Next.js, the route.js file plays a crucial role in the App Router (introduced in Next.js 13) by defining and managing routing configurations. This file helps in customizing the behavior of routes, including rendering components, handling dynamic segments, and applying middleware.In this article,
3 min read
Next.js Functions: useParams
Next.js is known for its ability to create dynamic and highly optimized web applications. Among them, useParams allows you to access route parameters and enhance the interactivity and functionality of the applications. In this article, we will explore what useParams is and how it works.What is usePa
4 min read