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

КОМЕНТАРІ • 122

  • @hamedbahram
    @hamedbahram  8 місяців тому +7

    UPDATE: I've updated the code to also pass the `response` object down in the middleware chain.

    • @OutrospectiveOfficial
      @OutrospectiveOfficial 8 місяців тому +1

      Thank you for this!

    • @hamedbahram
      @hamedbahram  8 місяців тому

      @@OutrospectiveOfficial anytime!

    • @sansonov
      @sansonov Місяць тому +1

      Where are we using the event that is being passed from one to another? Do we need that? If yes, could you pls explain?

    • @hamedbahram
      @hamedbahram  Місяць тому

      @@sansonov It's all in the request and response object that we're passing down the chain.

  • @samislam2746
    @samislam2746 4 місяці тому +6

    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.

    • @hamedbahram
      @hamedbahram  4 місяці тому

      I agree, it would have made more sense if you could stack middlewares in NextJs natively.

  • @user-hr4rl2cz1h
    @user-hr4rl2cz1h 11 місяців тому +8

    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!

    • @hamedbahram
      @hamedbahram  11 місяців тому

      Thanks Osama! I appreciate your comment. I'm glad you find the content useful.

  • @buddy.abc123
    @buddy.abc123 11 місяців тому +3

    I wish this video existed a few weeks back when I was battling with this 😂. Thanks for sharing

    • @hamedbahram
      @hamedbahram  11 місяців тому +1

      Send me a little comment next time you are battling with something ;)

  • @hamed4451
    @hamed4451 11 місяців тому +1

    it was perfect Hmaed jan, you mixed the composition pattern and recursive together to create multiple chaining middleware ... well done brother

    • @hamedbahram
      @hamedbahram  11 місяців тому +1

      Thank you! This was inspired by Jasser's blog post, so the credit goes to him :)

    • @hamed4451
      @hamed4451 11 місяців тому +1

      @@hamedbahram but i've learned it from you , so thank both of u guys :))

    • @hamedbahram
      @hamedbahram  11 місяців тому +1

      @@hamed4451 My pleasure!

  • @techknowledgebase4504
    @techknowledgebase4504 11 місяців тому +1

    It's awesome. 🎉 Your earlier reply I was learn from blog. Now revise with video

  • @muhammahanisuzzaman5493
    @muhammahanisuzzaman5493 11 місяців тому +1

    Top Level Content... Jajakallah! Keep going brother...

  • @OleJrgensen
    @OleJrgensen 9 місяців тому +1

    Thank you Hamed. You are better than good. I always give you two thumbs up :)

    • @hamedbahram
      @hamedbahram  9 місяців тому

      Thank you Ole! I appreciate it. Glad you find the content helpful.

  • @alamarnissi529
    @alamarnissi529 10 місяців тому +1

    Thank you very much Sir ❤ Really valuable content

  • @emreozturk1389
    @emreozturk1389 11 місяців тому +1

    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.

    • @hamedbahram
      @hamedbahram  11 місяців тому

      Absolutely! thanks for the comment, I appreciate it!

  • @billybob01234567
    @billybob01234567 Місяць тому +1

    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

    • @hamedbahram
      @hamedbahram  Місяць тому

      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.

  • @kennedyfreitas7548
    @kennedyfreitas7548 4 місяці тому +1

    amazing content sir

  • @ajayshahnew
    @ajayshahnew 6 місяців тому +1

    subscribed now based on your way of explaining

    • @hamedbahram
      @hamedbahram  6 місяців тому

      Welcome to the channel :)

  • @canklc5772
    @canklc5772 8 місяців тому +1

    Crystal clear

  • @aburaihan-py4vi
    @aburaihan-py4vi 7 місяців тому

    excellent!!!

  • @user-co1yn3bm7m
    @user-co1yn3bm7m 11 місяців тому +1

    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?

    • @hamedbahram
      @hamedbahram  11 місяців тому

      Absolutely 💯 you can add more conditional layers to your middleware logic.

  • @yaroslavraksha6747
    @yaroslavraksha6747 11 місяців тому +1

    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!

    • @hamedbahram
      @hamedbahram  11 місяців тому +1

      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

  • @christianhoffmann7284
    @christianhoffmann7284 10 місяців тому +1

    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 /

    • @hamedbahram
      @hamedbahram  10 місяців тому +1

      I think it'd be easier to use conditional statements inside each middleware to check the `path`.

    • @christianhoffmann7284
      @christianhoffmann7284 10 місяців тому

      @@hamedbahram yeah, that‘s what I reckoned. so that config object is for simple use cases where you have only that one middleware, huh!?

  • @AntoineGuglielmi-zo9uc
    @AntoineGuglielmi-zo9uc Місяць тому

    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 ?

    • @hamedbahram
      @hamedbahram  Місяць тому

      Use if conditionals to check the pathname inside the middlewares.

  • @MDKhan-ww5tp
    @MDKhan-ww5tp 11 місяців тому +8

    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

    • @hamedbahram
      @hamedbahram  11 місяців тому +2

      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

    • @MDKhan-ww5tp
      @MDKhan-ww5tp 11 місяців тому +3

      @@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

    • @hamedbahram
      @hamedbahram  11 місяців тому +2

      @@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

    • @nirjoyhasanantor3149
      @nirjoyhasanantor3149 11 місяців тому +2

      ​@@hamedbahramsir I am also interested in I saw your video but I didn't find where you did this what "md khan" talking about

    • @MDKhan-ww5tp
      @MDKhan-ww5tp 11 місяців тому +2

      @@hamedbahram Thanks sir but i am little bit of confused there and i did tried the getServerSession and it gives me a strange error

  • @Gorr1995
    @Gorr1995 6 місяців тому +1

    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

    • @hamedbahram
      @hamedbahram  6 місяців тому +1

      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.

    • @Gorr1995
      @Gorr1995 6 місяців тому +1

      @@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.

    • @hamedbahram
      @hamedbahram  6 місяців тому

      @@Gorr1995 there you have it :)

  • @Helixr
    @Helixr 9 місяців тому +3

    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.

    • @hamedbahram
      @hamedbahram  9 місяців тому +1

      Absolutely! I have that video in my schedule.

    • @in43sh
      @in43sh 8 місяців тому +1

      I am also looking for a solution to this

    • @mcFishXtraMayo
      @mcFishXtraMayo 8 місяців тому

      any updates on this? I am having a lot of headaches... can't wait for your video@@hamedbahram

  • @estevanulian
    @estevanulian 18 днів тому

    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?

    • @estevanulian
      @estevanulian 18 днів тому

      to solve this problem temporarily, the middleware responsible for these configurations was placed last in the array

    • @hamedbahram
      @hamedbahram  18 днів тому +1

      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.

    • @estevanulian
      @estevanulian 18 днів тому

      I don't know if I was able to express myself well. 🤭

  • @keiji0075
    @keiji0075 11 місяців тому +1

    can I know which extension your vscode font comes from? It's very good for me. thankyou

    • @hamedbahram
      @hamedbahram  11 місяців тому

      My font is operator mono and the theme is dark+ with italics.

  • @OleJrgensen
    @OleJrgensen 9 місяців тому +3

    Do you have an example where you actually use this technique to chain next-auth and next-intl ?

    • @hamedbahram
      @hamedbahram  9 місяців тому +1

      I will create a video on this soon 🙂

  • @in43sh
    @in43sh 8 місяців тому +1

    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?

    • @hamedbahram
      @hamedbahram  8 місяців тому +1

      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.

    • @in43sh
      @in43sh 8 місяців тому +1

      @@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.

    • @hamedbahram
      @hamedbahram  8 місяців тому +1

      @@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 :)

  • @nickolaki
    @nickolaki 9 місяців тому +1

    Can you do the same with api route handlers?

    • @hamedbahram
      @hamedbahram  9 місяців тому

      Good question! Yes you can. That's an interesting idea.

  • @hooyah
    @hooyah 11 місяців тому +1

    i need nextjs like laravel, everything i need is ready lol 🤣🤣

    • @hamedbahram
      @hamedbahram  11 місяців тому

      I'm not familiar with laravel!

  • @danberger18
    @danberger18 10 місяців тому +1

    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).

    • @hamedbahram
      @hamedbahram  10 місяців тому

      What would be the use case for a top level await?

  • @Vantivify
    @Vantivify 11 місяців тому +1

    I wonder if its still the case that just adding middleware.ts file adds 100 ms overhead to every request it runs on?

    • @hamedbahram
      @hamedbahram  11 місяців тому

      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.

  • @redbeardjunior
    @redbeardjunior 4 місяці тому +1

    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 ?

    • @hamedbahram
      @hamedbahram  4 місяці тому

      You can always right all the logic in one single middleware function.

    • @redbeardjunior
      @redbeardjunior 4 місяці тому

      @@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...

  • @healingwithlove8614
    @healingwithlove8614 11 місяців тому +1

    Is there any way to put phone authentication in next auth with OTP without twilio api sir if you know please let me know?

    • @hamedbahram
      @hamedbahram  11 місяців тому

      Good question. I'm not sure if there is a way to that with NextAuth! I'll look into it.

  • @khaledabderrahmenehabouche4633
    @khaledabderrahmenehabouche4633 4 місяці тому +1

    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

    • @hamedbahram
      @hamedbahram  4 місяці тому

      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

    • @khaledabderrahmenehabouche4633
      @khaledabderrahmenehabouche4633 4 місяці тому

      thank you@ahram , i appreciate it

    • @khaledabderrahmenehabouche4633
      @khaledabderrahmenehabouche4633 4 місяці тому +1

      thank you@@hamedbahram , i appreciate it

  • @mdkawsarislamyeasin4040
    @mdkawsarislamyeasin4040 6 місяців тому +1

    But what if I have different route or matcher config
    How can I implement that ?

    • @hamedbahram
      @hamedbahram  6 місяців тому

      Conditional statements inside middleware functions.

  • @mmtrrz
    @mmtrrz 9 місяців тому +1

    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.

    • @hamedbahram
      @hamedbahram  9 місяців тому

      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.

    • @mmtrrz
      @mmtrrz 9 місяців тому +1

      @@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.

    • @hamedbahram
      @hamedbahram  9 місяців тому

      @@mmtrrz for sure!

  • @eniolaadejori9114
    @eniolaadejori9114 10 місяців тому +1

    What of the config, what if ypu want the different middlewares tonrun in different paths?

    • @hamedbahram
      @hamedbahram  10 місяців тому

      You can use conditional statement inside each middleware to check the `path` and decide if that middleware should run.

  • @user-hf6uo6zw3w
    @user-hf6uo6zw3w 4 місяці тому +1

    But how do I ensure that the matcher constant does not affect my other middleware functions? I want each function to have a matcher

    • @hamedbahram
      @hamedbahram  4 місяці тому

      As of now there is only one matcher, you can use conditional check inside each middleware to decide what happens.

    • @user-hf6uo6zw3w
      @user-hf6uo6zw3w 4 місяці тому

      @@hamedbahramOk man, Thank you

  • @marcintichoniuk6554
    @marcintichoniuk6554 10 місяців тому +1

    What about response object? How to access it?

    • @hamedbahram
      @hamedbahram  10 місяців тому

      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.

  • @devomor8731
    @devomor8731 11 місяців тому +2

    Great video! Just one question 🙋‍♂️ what to do if I want match different routes for different middlewares?

    • @hamedbahram
      @hamedbahram  11 місяців тому +1

      You need to use conditional statements inside each middleware to check the pathname and decide what needs to happen.

  • @JaisonJohn-vg6fw
    @JaisonJohn-vg6fw 3 місяці тому +1

    What if we want to use a middleware with its own matcher? right all these middlewares are going to work for the same matcher.

    • @hamedbahram
      @hamedbahram  3 місяці тому +1

      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.

    • @JaisonJohn-vg6fw
      @JaisonJohn-vg6fw 3 місяці тому

      @@hamedbahram We can hope that the NextJs team will bring a functionality to use multiple middleware with its own matcher.

  • @tjblackman08
    @tjblackman08 3 місяці тому +1

    I miss route-level middleware from next12

    • @hamedbahram
      @hamedbahram  3 місяці тому

      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.

  • @user-wn8dz1st3h
    @user-wn8dz1st3h 9 місяців тому +1

    You are not passing the response, if one of the middleware set cookies it is not gonna work.

    • @hamedbahram
      @hamedbahram  9 місяців тому

      Good point 🤔 let me look into it.

    • @hamedbahram
      @hamedbahram  8 місяців тому

      Thanks for flagging this, Ben! I've updated the code to pass the response object down the middleware chain.

    • @user-wn8dz1st3h
      @user-wn8dz1st3h 8 місяців тому

      @@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.

  • @alexandrmeyer
    @alexandrmeyer 3 місяці тому

    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

    • @hamedbahram
      @hamedbahram  3 місяці тому

      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

    • @alexandrmeyer
      @alexandrmeyer 3 місяці тому

      @@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

    • @alexandrmeyer
      @alexandrmeyer 3 місяці тому

      @@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.

  • @StephenRayner
    @StephenRayner 11 місяців тому +1

    With this negative look ahead my svg files go through the middleware 🤷

    • @hamedbahram
      @hamedbahram  11 місяців тому

      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.

  • @DaumChannelGamePart
    @DaumChannelGamePart 11 місяців тому

    If you want to debug like console.log, you'd better use for loop. Recursion is not good for debugging.

    • @hamedbahram
      @hamedbahram  11 місяців тому

      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.