Next.js Discord

Discord Forum

How can I implement dynamic redirections?

Unanswered
Mudi posted this in #help-forum
Open in Discord
MudiOP
In my application, redirections are configured in the CMS. I want to query for that data, and then use it to decide whether any given request should be redirected.

I wanted to do this with a middleware, because I don't think a catchall route in the app router can cancel and defer to other routes, like in the case where there is no matching redirection found.

In the middleware I can query for the data fine with fetch, and the logic to redirect or not redirect is easy enough to implement. That's all working.

But I've noticed that this is not the patched version of fetch which Next provides in other contexts, with caching built in. That's a problem, because I don't want this lookup to happen on every single request; I want to cache it for some period of time, maybe an hour.

I considered caching the response manually with redis, but on trying to import a library for redis I get errors saying the Vercel edge runtime doesn't support various node APIs that the redis libraries want to use.

I'm stuck. What options do I have?

24 Replies

you can create a route handler that returns the cached redirect list or use a caching service that works on the edge, like upstash
@Rafael Almeida you can create a route handler that returns the cached redirect list or use a caching service that works on the edge, like upstash
MudiOP
When you say use a route handler, you mean I'd somehow call this from the middleware?
How would I make it private? I don't want to expose the list of redirections.
I don't like the idea of using a caching service like upstash because I'm not even using Vercel; I should be able to use redis libraries just fine on the server where my next app is running.
to protect it you can use an env var and send it with the request, then check if it matches in the route handler
@Rafael Almeida yeah, you can fetch it from the middleware
MudiOP
Is there an example? I'm not sure what that'd look like. I don't see anything about fetching a route handler from other places in the app on the route handlers doc page
it is like any other fetch: const redirects = await fetch('yourapp.com/api/cms-redirects').then(r => r.json())
the difference is that you need the full URL instead of /api/cms-redirects because this runs in the server
MudiOP
Oh I see.
I guess I then need an exception in the middleware to let that one through without trying to find out if it matches a redirection pattern lol
MudiOP
Would you agree that this seems pretty... kludgey? Making a request like this?
not really, its just reaching to your server to know the redirects
it would be way faster if you eliminated the request altogether, but it would require a rebuild of the project when changing the list
MudiOP
Yeah I'll have to see how long the self-request takes
I can also see if needing a rebuild would fly. How do you think that would look? A separate task before the build to do the query and generate a file which the middleware can reference? Or were you imaginging something slicker?
yeah I would build a json with a script before build and import it in the middleware
I am thinking more about it, and if you are using the app dir, maybe you could do the same logic in the root layout? I am not sure but if this works you could just feth your CMS there and it will be cached by the fetch from Next
Baldfaced hornet
Hey @Mudi - I am having the exact same issue - did you manage to solve it?
@Baldfaced hornet Hey <@418938730284580876> - I am having the exact same issue - did you manage to solve it?
MudiOP
I implemented what Rafael above suggested (not his very latest suggestion though I should maybe come back to it). I made an API endpoint to determine whether a redirection exists or not, and calling that via http from the middleware. I don't like it, it feels dirty and is slow.
@Miguel Did you ever find a better solution? It seems like unstable_cache doesn’t work in a middleware.ts file
MudiOP
No but it looks like there are plans for later versions of Next to support different edge runtimes, which would remove the restrictions on what packages can run there when you're not running on Vercel's infra.
Yeah I’m self hosting, so Nextjs blocks features that run on Vercel to be ran outside of it. I had no clue.