Chain Multiple Middleware Functions in NextJs 13

Поделиться
HTML-код
  • Опубликовано: 4 авг 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

Комментарии • 127

  • @hamedbahram
    @hamedbahram  9 месяцев назад +8

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

    • @OutrospectiveOfficial
      @OutrospectiveOfficial 9 месяцев назад +1

      Thank you for this!

    • @hamedbahram
      @hamedbahram  9 месяцев назад

      @@OutrospectiveOfficial anytime!

    • @sansonov
      @sansonov 2 месяца назад +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  2 месяца назад

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

  • @samislam2746
    @samislam2746 5 месяцев назад +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 RUclipsr who's touching Nextjs app router shady parts and explaining them in comfort.

    • @hamedbahram
      @hamedbahram  5 месяцев назад

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

  • @user-hr4rl2cz1h
    @user-hr4rl2cz1h Год назад +9

    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  Год назад

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

    • @denisotim7640
      @denisotim7640 12 дней назад

      💯💯💯💯💯💯

  • @charliesta.abc123
    @charliesta.abc123 Год назад +3

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

    • @hamedbahram
      @hamedbahram  Год назад +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 Год назад +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 10 месяцев назад +1

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

    • @hamedbahram
      @hamedbahram  10 месяцев назад

      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 Год назад +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  Год назад

      Absolutely! thanks for the comment, I appreciate it!

  • @kennedyfreitas7548
    @kennedyfreitas7548 5 месяцев назад +1

    amazing content sir

    • @hamedbahram
      @hamedbahram  5 месяцев назад

      Thanks! appreciate that.

  • @ajayshahnew
    @ajayshahnew 6 месяцев назад +1

    subscribed now based on your way of explaining

    • @hamedbahram
      @hamedbahram  6 месяцев назад

      Welcome to the channel :)

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

  • @canklc5772
    @canklc5772 9 месяцев назад +1

    Crystal clear

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

  • @aburaihan-py4vi
    @aburaihan-py4vi 8 месяцев назад

    excellent!!!

  • @yaroslavraksha6747
    @yaroslavraksha6747 Год назад +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  Год назад +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 11 месяцев назад +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  11 месяцев назад +1

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

    • @christianhoffmann7284
      @christianhoffmann7284 11 месяцев назад

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

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

  • @in43sh
    @in43sh 9 месяцев назад +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  9 месяцев назад +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 9 месяцев назад +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  9 месяцев назад +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 :)

  • @Helixr
    @Helixr 10 месяцев назад +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  10 месяцев назад +1

      Absolutely! I have that video in my schedule.

    • @in43sh
      @in43sh 9 месяцев назад +1

      I am also looking for a solution to this

    • @mcFishXtraMayo
      @mcFishXtraMayo 9 месяцев назад

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

  • @estevanulian
    @estevanulian Месяц назад

    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 Месяц назад

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

    • @hamedbahram
      @hamedbahram  Месяц назад +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 Месяц назад

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

  • @MDKhan-ww5tp
    @MDKhan-ww5tp Год назад +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  Год назад +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 Год назад +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  Год назад +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 => ruclips.net/video/Eh3EpwqT4cM/видео.html

    • @nirjoyhasanantor3149
      @nirjoyhasanantor3149 Год назад +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 Год назад +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

  • @OleJrgensen
    @OleJrgensen 10 месяцев назад +3

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

    • @hamedbahram
      @hamedbahram  10 месяцев назад +1

      I will create a video on this soon 🙂

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

  • @HigherStudyAspirant
    @HigherStudyAspirant 6 дней назад +1

    Thanks. What if we have different matcher for the two middleware, Suppose I want one matcher to run on every path (Internationalization case) while for authentication, another matcher run on protected pages only. How can we handle this?
    middleware.js for Auth
    export { default } from "next-auth/middleware";
    export const config = {

    matcher: [
    // '/users'
    ]
    };
    and one more confusion, my translation is coming from backend, do I still need useTranslation hook and dictionary (en.json,de.json like files)

    • @hamedbahram
      @hamedbahram  6 дней назад

      Use a conditional statement in each middleware to determine the path and the logic required to execute.

  • @Vantivify
    @Vantivify Год назад +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  Год назад

      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.

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

  • @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 11 месяцев назад +1

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

    • @hamedbahram
      @hamedbahram  11 месяцев назад

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

  • @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 → ruclips.net/video/bFr2t68AABQ/видео.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 :)

  • @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 Год назад +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  Год назад

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

  • @theintegratorZ
    @theintegratorZ Год назад +2

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

    • @hamedbahram
      @hamedbahram  Год назад +1

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

  • @khaledabderrahmenehabouche4633
    @khaledabderrahmenehabouche4633 5 месяцев назад +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  5 месяцев назад

      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 5 месяцев назад

      thank you@ahram , i appreciate it

    • @khaledabderrahmenehabouche4633
      @khaledabderrahmenehabouche4633 5 месяцев назад +1

      thank you@@hamedbahram , i appreciate it

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

  • @mdkawsarislamyeasin4040
    @mdkawsarislamyeasin4040 7 месяцев назад +1

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

    • @hamedbahram
      @hamedbahram  7 месяцев назад

      Conditional statements inside middleware functions.

  • @hooyah
    @hooyah Год назад +1

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

  • @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 11 месяцев назад +1

    What about response object? How to access it?

    • @hamedbahram
      @hamedbahram  11 месяцев назад

      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.

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

  • @brenol2177
    @brenol2177 12 дней назад +1

    Why can't nextjs team make this system be default or a feature that you opt in...

  • @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. RUclips removes comments with links. It's named Next.js Clerk vs. NextIntl. Middleware clash. So if somebody knows the answer please help.

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

  • @StephenRayner
    @StephenRayner Год назад +1

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

    • @hamedbahram
      @hamedbahram  Год назад

      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.

  • @user-wn8dz1st3h
    @user-wn8dz1st3h 10 месяцев назад +1

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

    • @hamedbahram
      @hamedbahram  10 месяцев назад

      Good point 🤔 let me look into it.

    • @hamedbahram
      @hamedbahram  9 месяцев назад

      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.

  • @DaumChannelGamePart
    @DaumChannelGamePart Год назад

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

    • @hamedbahram
      @hamedbahram  Год назад

      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.