Chain Multiple Middleware Functions in NextJs 13
Вставка
- Опубліковано 16 лип 2024
- This video looks at chaining multiple middleware functions in NextJs 13.
👉🏼 The Ultimate NextJs Course
🔗 www.hamedbahram.io/courses/ne...
👉🏼 Project source code (Github)
🔗 github.com/HamedBahram/next-m...
👉🏼 Inspired by Jasser's code ↓
🔗 github.com/jmarioste/next-mid...
Chapters
0:00 Intro
1:00 Simple middleware
3:00 Add second middleware
4:30 Simple composition
6:25 Add higher-order functions
10:00 Add the chain method
15:10 Reorganizing our middleware files
19:00 Outro
UPDATE: I've updated the code to also pass the `response` object down in the middleware chain.
Thank you for this!
@@OutrospectiveOfficial anytime!
Where are we using the event that is being passed from one to another? Do we need that? If yes, could you pls explain?
@@sansonov It's all in the request and response object that we're passing down the chain.
It was much easier in express. I think Nextjs Team should include the necessary utilities such as this chain function with the next package.
+ every video I learn something new from you. I think you're the only UA-camr who's touching Nextjs app router shady parts and explaining them in comfort.
I agree, it would have made more sense if you could stack middlewares in NextJs natively.
Sir you are doing tremendous job. Everyone is creating just the clones but thankfully you are covering all the important topics on which even senior developers are struggling due to lack of resources available on Next13 official docs. Hats off!
Thanks Osama! I appreciate your comment. I'm glad you find the content useful.
I wish this video existed a few weeks back when I was battling with this 😂. Thanks for sharing
Send me a little comment next time you are battling with something ;)
it was perfect Hmaed jan, you mixed the composition pattern and recursive together to create multiple chaining middleware ... well done brother
Thank you! This was inspired by Jasser's blog post, so the credit goes to him :)
@@hamedbahram but i've learned it from you , so thank both of u guys :))
@@hamed4451 My pleasure!
It's awesome. 🎉 Your earlier reply I was learn from blog. Now revise with video
Great 👍
Top Level Content... Jajakallah! Keep going brother...
Thank you!
Thank you Hamed. You are better than good. I always give you two thumbs up :)
Thank you Ole! I appreciate it. Glad you find the content helpful.
Thank you very much Sir ❤ Really valuable content
Glad to hear that!
wow, it's really such clean approach to middlewares. please keep going like this videos. i'm sure it will be a great inspiration for everyone.
Absolutely! thanks for the comment, I appreciate it!
Really nice video mate but just FYI the recursive middleware within the chain function is going to execute in reverse meaning if you want to kill an execution path and return a response (e.g. unauth 403) then the entire chain still has to execute
Hmm 🤔 good point! I can’t think of a solution to return early while also being able to forward the response unless we throw an error and skip the recursion.
amazing content sir
Thanks! appreciate that.
subscribed now based on your way of explaining
Welcome to the channel :)
Crystal clear
Glad to hear that!
excellent!!!
Cheers!
Thank you for the awesome video, definitely going to rewatch it and try myself!
If we had multiple middleware arrays for different routes. Could we add a layer to check the pathname and pass the middleware array to chain() accordingly?
Absolutely 💯 you can add more conditional layers to your middleware logic.
Great job! Can you please tell us the way we can provide different matchers for each middleware? Since, in your example, we have one global matcher for every middleware. Thanks!
For now there is no way to define different matchers. You need to use conditional statements inside each middleware to check the `pathname` and decide whether or not you want to run the middleware. You can read more about this in the docs => nextjs.org/docs/app/building-your-application/routing/middleware#conditional-statements
Great Video. Can I also export separate configs for different middlewares in the chain? Think of a next-intl middleware for i18n that should match everything except for /api/** and another middleware for auth that should only match everything except /
I think it'd be easier to use conditional statements inside each middleware to check the `path`.
@@hamedbahram yeah, that‘s what I reckoned. so that config object is for simple use cases where you have only that one middleware, huh!?
Hello ! Thank you so much for these explanations. But, what if I want middleware1 to be running on specific routes, and middleware2 to be running on other specific route ? Does anyone know about it ?
Use if conditionals to check the pathname inside the middlewares.
the thing i wanted video on but i am excited to see how can i run a middleware with next auth it is simple to do but i want to make sure that like this
you know we can authorize a user through middleware and we have to set matcher for routes to authorize for example in this case it is - ['/','/home','/profile'] these would be authorized
and my middleware will only run in these routes
but what if i have to do something where i don't not authorizing the pages but i want to run simple middleware on those pages for example in this case it is ['/about','/help','/learn-more'] how would i run the middleware in these pages?
Can you please make a video on that please
Good question. You cannot use the `config` matcher in those cases, you should use conditional statements inside the function to determine which paths your middleware will run on. you can see an example here => nextjs.org/docs/app/building-your-application/routing/middleware#conditional-statements
@@hamedbahram Thanks sir but can you tell me how can i authorize inside the conditional statement? i am new to next auth or it would be great if you make a video on it
@@MDKhan-ww5tp There is a video on the channel where I demonstrate everything you need to know to protect you app using NextAuth! you can watch it here => ua-cam.com/video/Eh3EpwqT4cM/v-deo.html
@@hamedbahramsir I am also interested in I saw your video but I didn't find where you did this what "md khan" talking about
@@hamedbahram Thanks sir but i am little bit of confused there and i did tried the getServerSession and it gives me a strange error
Hi Hamed. Thanks for your tutorial first of all.
The second thing that I wanted to ask you is: what if we have two middlewares :
- FIRST -> withAuth(func, options) -> returns middleware - from Next auth package with its own { config : matches: '...'},
- SECOND locale -> React-intl middleware that returns return i18nRouter(request, i18nConfig) and this middleware has matches config)
The question is: Can I split matches config through different middleware?!
I would be glad if you can help
It's not impossible to merge two configs and export one at the end, but I think you'd be better off using conditionals inside each middleware and defining when it should run. Watch this → ua-cam.com/video/bFr2t68AABQ/v-deo.html.
@@hamedbahram Thank you. Now it's getting more clear what to do next. Weird that I didn't get that video when I surfed through the internet.
@@Gorr1995 there you have it :)
Hello, I am trying to implement the chain middleware from your previous video with i18n and next auth but I cant get both of them to work.Can you please make a video on how to combine them both because i see a lot of posts on the web talking about this but none of them seems to get them work together.Thanks in advance for your great videos.
Absolutely! I have that video in my schedule.
I am also looking for a solution to this
any updates on this? I am having a lot of headaches... can't wait for your video@@hamedbahram
Hello, my friend. First of all, thank you very much for the content, it's invaluable. I'm in a situation where I need three middlewares, only one of which needs to return the header globally. However, it's not working as expected. Is there a way to make NextResponse keep sending the response data (headers) to the last middleware?
to solve this problem temporarily, the middleware responsible for these configurations was placed last in the array
My pleasure! Yes, I've actually updated the code in the repo to pass the response object down in the middleware chain. Have a look at the code.
I don't know if I was able to express myself well. 🤭
can I know which extension your vscode font comes from? It's very good for me. thankyou
My font is operator mono and the theme is dark+ with italics.
Do you have an example where you actually use this technique to chain next-auth and next-intl ?
I will create a video on this soon 🙂
Hi Hamed, thank you for your content on NextJs. As someone mentioned below, there is no solution for the combination i18n + next auth middleware anywhere to be found. Also, is it possible to have multiple config path matchers for different milddleware?
I'll create that video next week since so many people have asked about it. Unfortunately there can only be one config for your middleware.
@@hamedbahram that's understandable, but it's very possible that some pages that need to be internationalized, don't require user authentication. like some static informational pages.
@@in43sh Absolutely you can identify the paths that your auth middleware should run on either inside your middleware config or with conditional statements inside the middleware itself. I'll show that in the upcoming video :)
Can you do the same with api route handlers?
Good question! Yes you can. That's an interesting idea.
i need nextjs like laravel, everything i need is ready lol 🤣🤣
I'm not familiar with laravel!
Was anyone able to achieve this with asynchronous middleware? Next.js does not permit topLevelAwait, so you cannot just plug in: export default await chain(asyncMiddlewares).
What would be the use case for a top level await?
I wonder if its still the case that just adding middleware.ts file adds 100 ms overhead to every request it runs on?
It depends on where you are deploying your middleware function and what you're doing inside of it, for example if you're hitting a database deployed to a different region from your middleware edge functions, you would experience latency.
I'm getting stuck some how i'm trying to implement a logging and a next-auth/middleware in one or 2 files. some how combining wont work.
I have searched the internet for days any surgetions ?
You can always right all the logic in one single middleware function.
@@hamedbahram thank you for your reply trying some how its not working I posted about it on stack overflow but no response so far ! I will keep looking in to it...
Is there any way to put phone authentication in next auth with OTP without twilio api sir if you know please let me know?
Good question. I'm not sure if there is a way to that with NextAuth! I'll look into it.
My problem is that i have différent middlewares and différent matcher path for each one , for exemple having path1 2 and 3 in middleware1 and only path 2 and 4 in middleware 2 , and i dont Know how to make each middleware treat only his paths
You need to check the path inside your middlewares and conditionally apply the logic if it's the target paths. Read more here → nextjs.org/docs/app/building-your-application/routing/middleware#conditional-statements
thank you@ahram , i appreciate it
thank you@@hamedbahram , i appreciate it
But what if I have different route or matcher config
How can I implement that ?
Conditional statements inside middleware functions.
How do you use this with NextAuth's "withAuth" Middleware? How do you protect the api routes? I am getting strange behavior, when directly accessing the API, it's working but when accessing this api via any other app route, it's unauthorized, not setting the token.
You'd need to forward the `headers` to the next response. I'll be covering this in a video soon. It's been long overdue.
@@hamedbahram Thank you for prompt response, however I've resolved the issue but would like to implement it via Middleware. I'll wait for the video.
@@mmtrrz for sure!
What of the config, what if ypu want the different middlewares tonrun in different paths?
You can use conditional statement inside each middleware to check the `path` and decide if that middleware should run.
But how do I ensure that the matcher constant does not affect my other middleware functions? I want each function to have a matcher
As of now there is only one matcher, you can use conditional check inside each middleware to decide what happens.
@@hamedbahramOk man, Thank you
What about response object? How to access it?
Good question! you can access the `NextResponse` object in your last middleware in the `chain` function or any other higher order middleware functions like the `withMiddleware1` in our example.
Great video! Just one question 🙋♂️ what to do if I want match different routes for different middlewares?
You need to use conditional statements inside each middleware to check the pathname and decide what needs to happen.
What if we want to use a middleware with its own matcher? right all these middlewares are going to work for the same matcher.
As of now, you can only have one main `middleware.js` file with matcher, the rest of the functions need to use conditionals if statements to implement the required logic.
@@hamedbahram We can hope that the NextJs team will bring a functionality to use multiple middleware with its own matcher.
I miss route-level middleware from next12
I can see why... the logic was divided into separate middleware functions but on the other hand, it was hard to manage all those files together.
You are not passing the response, if one of the middleware set cookies it is not gonna work.
Good point 🤔 let me look into it.
Thanks for flagging this, Ben! I've updated the code to pass the response object down the middleware chain.
@@hamedbahram Cookies work now. But this is very strange to define the response in the first middleware. If middleware cannot be removed or be swapped then no point in doing middleware, you can simply do all in a file. One more thing is NextResponse.redirect doesn't work, i.e. there is no way to stop the execution of the first middleware.
I am crying now. I am trying to resolve Clerk authentification vs. Next Intl... I asked on Stack overflow and somebody suggested middleware chaining, so started to search and found this video.... It looks like a solution, but I don't understand a thing. I mean, I understand the concept, but can't make sense of it on Clerk/Next-intl example. Aaaaaahhhh
Clerk's middleware makes this easy by implementing the `beforeAuth` function. See here → clerk.com/docs/references/nextjs/auth-middleware#use-before-auth-to-execute-middleware-before-authentication
@@hamedbahram thank you, but this was my initial attempt. I could not do it right, so I started to search for alternative solution and ended up here. I guess, I can't post links here, so it is on stack overflow slash 78306404 slash next-js-clerk-vs-nextintl-middleware-clash
@@hamedbahram Thank you, but it was my initial attempt. It didn't work for me, so I started to search for alternative solutions. And ended up here after some tip on stack overflow. UA-cam removes comments with links. It's named Next.js Clerk vs. NextIntl. Middleware clash. So if somebody knows the answer please help.
With this negative look ahead my svg files go through the middleware 🤷
There are two ways you can go about solving this, one is to statically import your svg file in the component that uses it, so it can be served from `_next/static` which is already excluded from the middleware. The second approach is to add `.+svg` to the end of your matcher regular expression, to also skip the `.svg` files you're directly serving from your `public` folder.
If you want to debug like console.log, you'd better use for loop. Recursion is not good for debugging.
This is not for debugging, this was just an example of whatever logic you want to run inside of a middleware, I used console.logs to show when each middleware is running.