-
Notifications
You must be signed in to change notification settings - Fork 27.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] server(less) middleware #7208
Comments
This new feature is aimed at supporting projects like next-i18next by default, which currently requires a custom server, cc @isaachinman Relevant code: https://github.com/isaachinman/next-i18next/blob/master/src/middlewares/next-i18next-middleware.js#L52 |
What about React bugs that can be fixed ONLY by modifying the resulting HTML as a string? |
@timneutkens As discussed via Slack - just want to clarify that we're talking about vanilla Is that correct? |
@isaachinman yep! @ivan-kleshnin I don't understand how this relates, you'd be able to override |
Just a quick thought and potentially bikeshedding, but would it make sense to use the |
I'd rather stay with the Node.js
|
@timneutkens Agree with that completely. I was going to mention - there'd probably be room after this feature lands to churn out little packages to enable 1:1 replacement for things like Express. Much better to begin with Node defaults. |
I've been using this workaround which allows me to add middlewares to See a demo of adding ✅ Works for local dev/custom server ( |
Hey @timneutkens and @Timer - great to see v9 has landed. I do believe that first-class support for API routes is a monumental and vital step for NextJs. I've looked through #7297 and the new documentation, and it seems middleware support is not there yet, right? Would love to be able to rewrite |
Our enterprise would also love to see this. We have an internal authentication system that requires a custom server currently and being able to move that logic to middleware and remove the custom server would dramatically simplify our project upgrading (we have hundreds of projects using Next - each major upgrade has had a decent amount of pain and pushback, other than next 9 - thanks for the backwards compat!). |
Just my two cents here: Wouldn't make sense to be able to add a |
@zomars This is mostly relevant for actual frontend routes. It's already possible to use middlewares in your v9 API routes. |
@isaachinman Is there a fully working example you can refer to? |
@amardeep9911 I might be wrong, but one way is to wrap the handler function. |
Hi @timneutkens, I'm testing the experimental functionality of middleware (great by the way) but I can never access the request object, when I log the middleware context I have this > GET /
{
err: undefined,
req: undefined,
res: undefined,
pathname: '/',
query: { amp: undefined },
asPath: '/',
AppTree: [Function: AppTree]
} Should I create a separate issue? Or is that a normal restriction? |
@HelloEdit I seem to remember that req/res are undefined unless your page has .getInitialProps() function, because without getInitialProps your page may be static |
ho, thank you for your answer. but I sincerely hope that it is not the expected behavior: the middleware would lose all their interest if getInitialProps was required to make them work, or I missed a point 🤔 |
@timneutkens nice, looking forward to when this gets implemented :) question for you. would this affect the automatic static optimizations outlined here? |
It wouldn't work with static pages. |
Would love to see a
In addition, use an additional middleware function to check session authentication:
And then I manually wrap my API route(s) with them:
While it works, the downside is that every API page function needs to be manually wrapped with this |
@timneutkens Wanted to check why this RFC is still open. The changes at #7209 has been merged into canary. When will this be merged into master and available to use under Next.js 9. |
It's unlikely this will land anytime soon as it introduces quite a bit of additional complexity for no additional gain based on upcoming features. |
Hope the team will suggest alternative for using middleware in client-side or if we can't use middleware at client-side at all! Thanks! |
This proposal didn't cover client-side middleware. |
@timneutkens The current canary implementation involves maintaining a For example, I have a working prototype that utilizes the Server's next.config.js
Or, if you wanted to include your own middleware function(s), then that is also supported (all routes middleware or conditional routes middleware):
Then in the The advantage of this approach is that all of this abstracted from the developer, it's opt-in, doesn't require a Let me know what you think. |
@mattcarlotta that won't work as Also there's no clear correct behavior with introducing those methods, for example Next.js apps are increasingly hybrid of SSG / SSR and middlewares won't be able to run for static files as they'd be served from an edge cache. |
This case is covered by the rewrites/redirects and new data fetching methods btw. |
Hey @timneutkens, I know this feature is still experimental but do you think is there any potential problem using this only to set some cookies. We only have SSR pages. |
If you want to set cookies it's better to use API routes and redirect. |
Could this middleware be used in addition of I am asking this because our stack includes a headless CMS (Cockpit) and Next.js, doing the routing between the two is currently (really) hard (the routes being on the CMS, and slugs/URLs/pages could be added/removed/edited any time by an editor). In our scenario, the |
Hey all! We just launched an NPM library for Express style architecture in Next.js without adding an Express server. It might be helpful for your middleware challenges! Check it out if you're interested. https://github.com/oslabs-beta/connext-js |
@sarapowers I'm about to check this out - what's the minimum version of Next it can be used with? Thanks for sharing! |
@runofthemill At this point, Connext utilizes Next.js's API routes so 9.0 is the minimum version you'd need. We'd love to someday make it compatible with older versions though! |
This option was experimental and doesn't cover the hybrid nature of Next.js (both static and dynamic pages). It also doesn't cover the cases we wanted to cover with the option. The option also does not work in all targets and is an avenue for slowing down the application. Closes vercel#7208
Hey @timneutkens - just want to close the discussion off here with some clarifying points. There are two main reasons why
The second issue is helped along by However, we still need to execute language detection middleware for each incoming frontend request (and potentially 302 in some cases). If this RFC is no longer being considered, I'm wondering if you have a suggestions as to the "best practice" way to do that? I've set forward i18next/next-i18next#689 as an initial working idea of how to support serverless i18n with NextJs, and we're literally doing: const middlewares = nextI18NextMiddleware(nextI18Next)
for (const middleware of middlewares) {
await new Promise((resolve) => middleware(req, res, resolve))
} Inside of a wrapped |
Current plan is to have the notion of languages / language detection built into Next.js, that way we can make it work with both SSG and SSR and have it work on the edge for the majority of cases. This will be similar to eg preview mode. |
Ah, I wasn't aware that was on the cards. Perhaps naively, I don't see how that would solve, or even simplify, the problem of localisation in NextJs apps. Language detection itself is a solved problem. The real trick with universal/NextJs apps is handling language detection in conjunction with saved state via cookies, and potential state via routing (locale subpaths). There may be ways to get close to fully-static solutions by taking opinionated approaches to routing, but many valid use cases will always require middleware. |
Can we get more info on that @timneutkens ? In what aspects of I18n will Next.js be involved and in what it won't? |
Can't share details yet. Still need to write up a RFC for it. |
Hi, i18n support in nextjs10 is nice. Thanks |
Is there any progress on this feature? There really should be a way to add a middleware for all pages, not just APIs, that can set headers/cookies globally without disabling automatic static optimization. |
This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Feature request
Currently there are a lot of users that create a custom server to do
middleware
behavior, for example server-side parsing of request bodies, cookies etc. Currently Next.js provides no way of handling this without a custom server. Meaning it can't be done in serverless / other environments.Describe the solution you'd like
Ideally users would define middleware as a top level export. Meaning that pages can define middleware requirements:
However this also introduces the complexity of having to code-split / tree shake away user imports that are server-only.
So for the initial implementation (and incrementally working towards the implementation above) I'd start with supporting middleware in
pages_document.js
which is always server-side rendered so it makes sense to have it there.One thing that was brought up is "why can't this just be done in getInitialProps of _document".
The reason that we need a new method is that the lifecycle of calling getInitialProps looks like this:
renderPage
renderPage
calls React'srenderToString
and returns the html, head tags and styles.renderToStaticMarkup
is called to render the _document shellGenerally when using middleware it has to be called before
getInitialProps
because you could be parsing something needed ingetInitialProps
So the middleware has to be called earlier.
Meaning the lifecycle would look like:
renderPage
renderPage
calls React'srenderToString
and returns the html, head tags and styles.renderToStaticMarkup
is called to render the _document shellSo for the initial implementation we'd want something like:
The text was updated successfully, but these errors were encountered: