Fallback after getServerSideProps() returns notFound #38839
Replies: 6 comments 12 replies
-
Is there a less hacky solution? |
Beta Was this translation helpful? Give feedback.
-
Main problem with custom server solution is that it doesn't support Vercel deployments. And looks like now there is no way to make it alive on Vercel. We use
and expect that returning |
Beta Was this translation helpful? Give feedback.
-
Ok, there is a working solution that also supports Vercel deployments. Instead of returning import httpProxy from "http-proxy";
import { GetServerSidePropsContext } from "next";
// In TS we say that it returns `NotFound` type but in reality
// `Promise` is never resolved and `http-proxy` generates response using `context.res` directly
type NotFound = { notFound: true };
const proxyToBackend = async (context: GetServerSidePropsContext): Promise<NotFound> =>
new Promise(() => {
context.res.setHeader("Cache-Control", "no-cache");
// In some cases `changeOrigin: true` should be used
const proxy = httpProxy.createProxyServer();
proxy.web(context.req, context.res, { target: process.env.RAYCAST_STORE_HOST });
});
export default proxyToBackend; |
Beta Was this translation helpful? Give feedback.
-
Hi folks, I just wanted to add some support for this idea. My team is working on supporting some legacy rewrites/redirects in a NextJS web app where the functionality may be different depending on the specific endpoint/page the user lands on. While we are able to return a redirect or a 404, if we were also able to proxy (or rewrite) an endpoint as an option we thought it would be a much cleaner developer experience. While we are currently considering a handful of other options for the feature, we believe this would be a powerful and useful feature to include in NextJS. To go into a bit more detail on our use case, in essence, we have a legacy database with over 2 million rows of URL slugs to content that may have had its slug updated or manually input. These slugs live alongside a rewrite/redirect destination. A large subset of the contents of this table were deemed important to reimplement at a business level. Since these routes may surface either a redirect or a rewrite/proxy, one of the solutions we were looking into was using NextJS middleware to test the current route against the database. We were running into limitations with the Edge Runtime communicating with Redis, where we cache route mappings. Since these are relatively high traffic routes, we were hesitant to put an extra HTTP request in front of every URL that matched. Ideally we would be able to modify the page route configurations we intend to rewrite/redirect to and within their getServerSideProps return the proxy/rewrite to the appropriate route. We understand that supporting this when an external ( |
Beta Was this translation helpful? Give feedback.
-
A better work around, and the one I ended up implementing, was using nginx to catch a 404 from Next.js and retry the request on the legacy system. This worked surprisingly well, but was obviously more complex. |
Beta Was this translation helpful? Give feedback.
-
Any news ? This feature can be added in next ❤️ |
Beta Was this translation helpful? Give feedback.
-
Describe the feature you'd like to request
In order to transition from a legacy website to Next.js we need a series of fallbacks.
The problem is that Next.js does not allow one to have multiple fallback routes. In other words, if I have a catch-all route like
pages/[[...path]].ts
and that routesgetServerSideProps()
returns{ notFound: true }
then thefallback
rewrites are not run.This is a problem during a transition from a legacy system because there is no way to say "we can handle some routes, some CMS objects, and everything else should fallback."
Describe the solution you'd like
I would like a configuration option that would allow Next.js to continue the routing process if the first matched found route intends to return a not found status.
For instance, perhaps instead of this:
A route could return something like:
This would allow each route to opt-into continuing the route matching.
This could also be useful in scenarios where you have something like this:
If you would like, the article, if not found, could continue to the next matched path (and so on and so forth) until something actually handles the response.
Alternatively, a more powerful API could be to allow a callback funciton to be invoked to make routing decisions. This could be part of the
rewrites
config. Perhaps thesource
could accept an async callback function that recives a the current request object. This function wouldn't be called until the router failed to match anything before it.Yet another alternative could be to allow for middleware to opt-into retrieving the actual response and rewritting the request multiple times (until you get something other than a 404, etc.). I realize that would break streaming, but it feels less worse than the solution I came up with.
Describe alternatives you've considered
My first attempt was to simple try doing it what I expected. As the docs say:
That isn't completely accurate. If a route is matched, that route is used and the fallbacks are never called even if
{ notFound: true }
is returned. I kept getting the 404 page and never got to the fallback.My second attempt was to instantiate a Custom Server from within an API Route. This worked for a single request and I think there is a memory leak in doing this because it quickly crashed Node.
My third attempt was to implement a Custom Server from the root and prevent Next.js from sending a response before I inspect the response, determine it to be a 404, and re-render. I could not find an easy way to do this. Despite my efforts, the headers and body are written directly to the stream and unless I was to override the methods in the response object (eww) there wasn't a great way to do this.
My final attempt, and the only thing that seemed to reasonably work, was to implement a Custom Server from the root and attach the
app.render()
method to the response object and from there I could use it from an API route:and in the API route handler:
This isn't great, but it does work. I do get this warning in the console:
It feels like Next.js is missing a feature that would make a huge improvment on migrating from one system to another. Of course we wont need this features as soon as we are done with the migration.
Beta Was this translation helpful? Give feedback.
All reactions