Tips from open-source: How redirect in Next.js works under the hood
Ramu Narasinga
Posted on May 13, 2024
In this article, you will learn how redirect in next.js works under the hood by looking at the Next.js source code around redirect functionality.
My approach:
- Start from the `import { redirect } from "next/navigation"'
- Back trace the redirect function to redirect.ts file
- redirect.ts explained
- How does throwing an error make the redirect work?
- Check redirect.test.ts to understand the full context
- redirect-boundary.ts has the redirect functionality
1. Start from the import:
Redirect function is imported from next/navigation. You can read more about redirect at: https://nextjs.org/docs/app/api-reference/functions/redirect.
But where do I find the next/navigation code? You can find this code in navigation.js. This file basically exports the navigation.ts that is /packages/next/src/client/components.
2. Back trace the redirect function to redirect.ts file
Although, navigation.ts has 272 lines of code at the time of writing this article, what we are interested in is the export of “redirect” at the end of the file as shown below. Focus on what you are looking for, don’t let the other code distract you.
As you can see, redirect is an export from navigation.react-server.ts. Inside the navigation.react-server.ts, you will find that redirect function is, in fact, from redirect.ts.
I did not know nested exports. Interesting.
3. Render.ts explained
“Invoking the redirect() function throws a NEXT_REDIRECT error and terminates rendering of the route segment in which it was thrown.” — Nextjs docs
Let’s look at the code snippet that throws the error inside redirect.ts
4. How does throwing an error make the redirect work?
Redirect function throws an error that sets the error.digest, but it was not obvious as to how throwing an error makes the redirect work.
I searched long and hard, my initial thoughts were around trying to find that catch block since redirect throws an error. I scoured the server related files but of no use.
I kept at it until it started to make sense when I looked at redirect.test.ts
5. Check redirect.test.ts to understand the full context
This one time I read somewhere that you could use tests to understand the context of a function. Hence the reason why I checked the code in redirect.test.ts
It is evident from the test code that getURLFromRedirectError(err) is called. You will find this function react-boundary.ts
Okay, test calls this getURLFromRedirectError function but what’s the execution flow? What happens after the error is thrown? Making a search based on getURLFromRedirectError function, the following are the results:
6. redirect-boundary.ts has the redirect functionality
The answer is Next.js redirect uses useRouter hook and depending on redirect type, it either pushes or replaces the url
This redirect-boundary is part of app-router code as shown below
when the error is thrown from redirect, it is caught by the redirect-boundary and redirect occurs. It is quite fascinating to find that redirect function itself does not do the redirect but rather redirect-boundary inside app-router handles the routing logic.
Conclusion:
I do not know why this API is designed this way but we could use this pattern of throwing an error from your npm package and use a boundary , preferably at the root level, to catch that error and do your thing.
If it wasn’t for me checking the redirect.test.ts code I would not have been able to figure out how the redirect works because I was hoping to find some sort out catch block in the redirect.ts but that is not the case.
Feel free to reach out to me at ramu.narasinga@gmail.com if you have any questions about this article.
Get free courses inspired by the best practices used in open source.
About me:
Website: https://ramunarasinga.com/
Linkedin: https://www.linkedin.com/in/ramu-narasinga-189361128/
Github: https://github.com/Ramu-Narasinga
Email: ramu.narasinga@gmail.com
Learn the best practices used in open source.
Further reading:
- https://github.com/vercel/next.js/blob/c1f8d9317588e51a8a31240f6add36b5f2c9f9bf/packages/next/src/client/components/navigation.react-server.ts
- https://github.com/vercel/next.js/blob/c1f8d9317588e51a8a31240f6add36b5f2c9f9bf/packages/next/navigation.js
- https://github.com/vercel/next.js/blob/c1f8d9317588e51a8a31240f6add36b5f2c9f9bf/packages/next/src/client/components/redirect.ts
- https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/redirect.test.ts
- https://github.com/vercel/next.js/blob/c1f8d9317588e51a8a31240f6add36b5f2c9f9bf/packages/next/src/client/components/redirect-boundary.tsx#L8
Posted on May 13, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
April 2, 2024