Blog Details
Ashraful Islam
15 Oct 2024
5 min read
Intercepting routes in Next.js introduces a flexible way to load content from one route without disrupting the current layout. This is especially helpful in scenarios where you want to maintain context while showcasing additional content, like displaying a photo in a modal without leaving the feed. Let’s explore how intercepting routes work and their benefits for soft and hard navigation.
Intercepting routes allow you to display content from another part of your application within the current view, keeping the user’s context intact. For example, if you have a photo feed, clicking on a photo might display it in a modal overlay, instead of taking the user to a different page entirely. This preserves the underlying feed and enhances the user experience by keeping navigation smooth and seamless.
Next.js introduces a specific convention for intercepting routes: the (..)
matcher. This allows you to specify how routes should be intercepted and how content from different segments should be loaded. Here’s how it works:
(.)
: Matches segments on the same level.( .. )
: Matches segments one level higher.( .. )( .. )
: Matches segments two levels higher.( ...)
: Matches segments from the root app directory.For instance, you can intercept a photo route inside a feed by creating a ( .. )photo
directory. This system uses route segments rather than file-system paths, making the routing more dynamic and intuitive.
One of the most common use cases for intercepting routes is building modals. By combining intercepting routes with Parallel Routes, you can solve common challenges related to modals, such as:
For example, if a user opens a photo modal from a gallery, they should be able to navigate back to the gallery or forward to the modal view without disrupting the flow.
Intercepting routes are not limited to photo galleries. Other common examples include:
/login
page for users who navigate directly to the login form.Let's set up the login modal that can be opened from the navbar and also have a dedicated /login
page.
//layout.js (Main layout with intercepting routes for login modal)
// app/layout.js
import { useRouter } from 'next/router';
export default function Layout({ children }) {
const router = useRouter();
return (
<html>
<body>
{/* Navbar with login button */}
<header>
<button onClick={() => router.push('/login')}>Login</button>
</header>
{/* Content */}
<main>{children}</main>
{/* Modal Route Handling */}
{router.pathname === '/login' && (
<LoginModal onClose={() => router.back()} />
)}
</body>
</html>
);
}
//login/modal.js (Login Modal)
// app/login/modal.js
export default function LoginModal({ onClose }) {
return (
<div className="modal-overlay">
<div className="modal-content">
<h2>Login</h2>
<form>
<label>Email:</label>
<input type="email" required />
<label>Password:</label>
<input type="password" required />
<button type="submit">Login</button>
</form>
<button onClick={onClose}>Close</button>
</div>
</div>
);
}
//login/page.js (Dedicated Login Page)
// app/login/page.js
export default function LoginPage() {
return (
<div>
<h2>Login Page</h2>
<form>
<label>Email:</label>
<input type="email" required />
<label>Password:</label>
<input type="password" required />
<button type="submit">Login</button>
</form>
</div>
);
}
In this setup, when the user clicks on the login button in the navbar, the login modal will appear via route interception (/login
). However, if the user directly navigates to /login
, the full page version of the login form will be displayed.
/cart
page.// layout.js (Main layout with intercepting routes for cart modal)
// app/layout.js
import { useRouter } from 'next/rou ter';
export default function Layout({ children }) {
const router = useRouter();
return (
<html>
<body>
{/* Navbar with cart button */}
<header>
<button onClick={() => router.push('/cart')}>Open Cart</button>
</header>
{/* Content */}
<main>{children}</main>
{/* Cart Modal Route Handling */}
{router.pathname === '/cart' && (
<CartModal onClose={() => router.back()} />
)}
</body>
</html>
);
}
//cart/modal.js (Cart Modal)
// app/cart/modal.js
export default function CartModal({ onClose }) {
return (
<div className="modal-overlay">
<div className="modal-content">
<h2>Your Shopping Cart</h2>
{/* Cart items here */}
<button onClick={onClose}>Close</button>
</div>
</div>
);
}
//cart/page.js (Dedicated Cart Page)
// app/cart/page.js
export default function CartPage() {
return (
<div>
<h2>Shopping Cart</h2>
{/* Cart items and checkout options */}
</div>
);
}
Here, when the user clicks on "Open Cart" in the navbar, the shopping cart modal opens without leaving the current page. But if the user directly navigates to /cart
, the dedicated full-page version of the cart is displayed.
Intercepting routes offer an elegant way to enhance user experience in Next.js by enabling smooth transitions and preserving context. Whether it’s displaying modals, sharing content through URLs, or managing complex navigation flows, intercepting routes provide the flexibility needed to build modern web applications. As you explore this routing paradigm, consider how it can improve your app’s navigation and user interface, ensuring a seamless and dynamic experience for your users.
Don’t worry, we don’t spam!