Next.js, a popular React framework, introduced an exciting feature with its version 13 release - Intercepting Routes. The essence of intercepting routes lies in the ability to display the content of a route without necessitating a full page switch, offering a more cohesive and dynamic user interface. Therefore, a user can provide share the link, and if they reload or directly access the URL, they will receive the full page.
Main Use Cases
- Login Modal
- Image Gallery/Photo Feed
- Dashboard
Login Example
Let's delve into a practical implementation of parallel routes and route interception by improving the login experience for our users. In this example, clicking the account icon triggers a modal that hosts the content of the login page. The URL reflects this change, switching to
/login.
All you need proceed with this tutorial is a simple page set up with an account icon or a link to login.
When we click the user icon, ordinarily, we would get redirected to the `/login/ page. However, we want to see it's contents but we don't want to move away from the homepage context.
@authModal/(.)sign-in/page.tsx
@modal
creates a slot. This is not the same as a route segment and is ignored by the file tree. The layout file closest to your slot will now accept @authModal as a prop.
(.)sign-in
will match the segment that is on the same level. So it will match the sign-in page that you have outside of the @authModal folder on the same level.
Now that we have the naming conventions out of the way, let's take a look at the full tree relevant to this.
Sign-in Page
(auth)/sign-in/page.tsx
import SignIn from "@/components/auth/SignIn"; const SignInPage = () => { return ( <section className=" flex-1 flex min-h-[calc(100vh-48px)] items-center"> <SignIn /> </section> ); }; export default SignInPage;
The
SignIn
component contains a simple form, but it's irrelevant to this so we don't need to get into that.
The Modal
import CloseModal from "@/components/auth/CloseModal"; import SignIn from "@/components/auth/SignIn"; const SignInModal = () => { return ( <div className="fixed inset-0 bg-zinc-900/40 z-20"> <div className="container flex items-center h-full mx-auto max-w-lg"> <div className="relative bg-gray-800 w-full h-fit py-20 px-8 rounded-lg shadow-md"> <div className="absolute top-4 right-4"> <CloseModal /> </div> <SignIn /> </div> </div> </div> ); }; export default SignInModal;
The code above is what we want to show instead of showing the full page that we would see if we went directly to /login page. We want this in a modal and so that is what we have here. Clicking close modal, will simply call router.back().
Above we can see, maybe not clearly enough, that we have an overlay for the modal which by using a combination of intercepting and parallel routes allows us to login via a modal whilst still appearing to be on the homepage and not losing context. If I close the modal, I simply return to the homepage URL.
Conclusion
By combining intercepting and parallel routes, we can stream multiple routes at once and have them intercepted to improve the user experience. It's a great feature that whilst confusing at first, is actually very easy to implement.