Redirecting with Style: Crafting Middleware Redirects in Next.js App Router
You may want to think about middleware in Next.js as the bouncer of your application. The middleware takes action before the app serves any page, whether it is the main welcome page or an auxiliary page. The bouncer will let you specify what actions to take on the predefined requests. It can be any action you want- like redirecting the user to a login screen, marking an old page for deprecation, or doing some A/B testing considerations.
In other parts of this tutorial, we will be using TypeScript so we will first create a 'middleware.ts' file. If you are not using TypeScript, you can create a javascript file and name it 'middleware.js'. In any case, every page will need to import some components from Next.js and implement the logic for URL validation function. From that point, it becomes trivial to decide whether to let them through or to redirect them elsewhere.
Moreover, this does not need to be executed on all the routes. The matcher refines the sender scope execution point, meaning you are not constrained to a single route. That is one area we will investigate in these pages.
⚙️ 1. Spinning Up Your Middleware File
To begin, create a middleware.ts file in the root folder of your project (or under /src if that is how you prefer organizing things). After that, pull the appropriate pieces that need to be fetched.
Isn’t that simple? This file will execute for every single request that is received—unless told otherwise. Next.js by Vercel - The React Framework.
Narrowing the Scope with matcher
Allowing middleware to run everywhere may slow things down and cause an infinite back and forth. Add a config block:
With this, you’re only intercepting traffic to those paths. No endless loops, promise. Next.js by Vercel - The React Framework,.
🔄 2. Your First Redirect
This one had you in the first half, didn’t it?
Inside your middleware function, look through the URL to decide:
“Here, anyone accessing /old-page is a smooth sail to /new-page. Notice that we use new URL('/new-page', request.url) so that we do not mess the domain or protocol or something unnecessarily” Next.js by Vercel - The React Framework.
Keeping a Sight on Your Private Routes (The Secret Ones😉)
What if you had your own personal dashboard/portal that you only wanted your users to access when logged in? It could function something like this:
In case you are not signed in or Authorized and you want to take a look into /dashboard/*, then you will immediately be taken to /login with no questions asked.
🏷️ 3. Combative Dynamism and Multi-Purpose Catch-All Routes
Perhaps your paths include variables such as blog slugs, not a problem at all:
The :slug* The pattern is capable of capturing every single blog URL, and inspecting that portion is almost instant.
📜 4. Redirects: Temporary vs. Permanent
Without any changes, NextResponse.redirect() defaults to issuing 307 Temporary Redirect, which is useful in those scenarios where it’s “Just this once.” For scenarios with “never coming back,” use 308 Permanent:
Increased SEO effectiveness. Help search engines reindex after shifting their focus to relying on updated current data available.
🛠️ 5. It’s the Applying That Counts
Test the app by running the command: npm run dev. Access your outdated URLs and see if it functions as intended.
Always ensure, not the very last, that is eventually, you check the status code returned (307 or 308) along with.
A step further, ensure the location header is positioning.
Check your Edge logs: From Vercel or other places, ensure your middleware is functioning where you expect them to. Otherwise, there can be other problems as well.
🤔 Troubleshooting Tips for easy debugging
Check for infinite loops your matcher may be in best case scenario looking parked at exclude target path.
Missing styles? Focus more at your underlying issues like, are styles load for redirected pages—don’t forget, middleware acts before layouts appear.
Stored 308 Redirects: You'd look stylish in a 308—popular with l337s. Until you are certain, play around with 307s first.
Less strenuous trace debugging...