The Ultimate Guide to Server Actions in NextJs 13 with Error Handling & Validation Using Zod

Поділитися
Вставка
  • Опубліковано 3 жов 2024

КОМЕНТАРІ • 78

  • @zrios
    @zrios Рік тому +2

    Amazing!! I used to implement Formik and Yup in client components but this approach is awesome, quicker and easier.
    Thanks for share

    • @hamedbahram
      @hamedbahram  Рік тому

      Glad to hear that! Same here, I used to use Formik + yup 💯

  • @og2t
    @og2t Рік тому +1

    Exactly what I needed in the right time, thx a lot for this Hamed.

  • @kyle-andrewgovinder9902
    @kyle-andrewgovinder9902 11 місяців тому +1

    Fantastic video
    Love all of your work
    Always learn so much

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

      Glad to hear that. I appreciate your support 🙏🏼

  • @gr8tbigtreehugger
    @gr8tbigtreehugger Рік тому +2

    Many thanks for this super helpful and timely video - was planning to learn and do exactly this today!

    • @hamedbahram
      @hamedbahram  Рік тому +1

      You're welcome! Glad to hear that!

  • @AfshinKaramifar
    @AfshinKaramifar Рік тому

    Khely Goooooliiii, Damet garm❤

  • @elvisc
    @elvisc 5 місяців тому +1

    Great stuff! One question: In your implementation towards the end, the "client side" validation still needs to go through the server action. Is there a way to do client side validation without calling the server action, while keeping the "action" prop in the element? The reason for keeping the action prop in the form element is so that this is the only way the `useFormState` from react-dom can track the form state.

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

      Good question, I believe you can create a client action from where you validate and call the server action.

  • @ahmedhussin5704
    @ahmedhussin5704 Рік тому +1

    Amazing tutorial .

  • @reiniervarkevisser
    @reiniervarkevisser Рік тому +1

    Thanks for this.👏

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

    Hey Hamed, I was watching your informative UA-cam video discussing the updates in Next.js 14. I'd love to learn more from your detailed notes in Notion about these updates. Would you mind sharing them with me? 🙂

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

      That was a lesson from my NextJs course. I'll publish the notes as a blog post at some point. Hopefully in the near future.

  • @Happyday-nn6rh
    @Happyday-nn6rh Рік тому +1

    very helpful video ❤‍🔥 and is updating video that is nice

  • @moteteletsa2034
    @moteteletsa2034 Рік тому +3

    Thank you so much for a wonderful video. It has added so much value in my understanding of Server Actions. Nonetheless, I am really struggling with using redirect when using server actions. Instead of updating the current page on which the form is, I need to redirect user to the next page. Can you show us how we can do that? Thank you for your good content as always.

    • @hamedbahram
      @hamedbahram  Рік тому

      You're welcome! I'm glad you found the videos helpful. In order to redirect the user to a different page you can use the `redirect` function from `next/navigation`. You can read more about it here => nextjs.org/docs/app/api-reference/functions/redirect

  • @JiNx-yf1ef
    @JiNx-yf1ef Рік тому

    Thank you so much 🙏 , I have learned a lot of things from you 🙏

    • @hamedbahram
      @hamedbahram  Рік тому

      Happy to hear that! I appreciate your comment.

  • @mrbanana6969
    @mrbanana6969 Рік тому +3

    Thanks for the great video, very informative - I learned a lot.
    I am wondering if you or anyone else is having problems with propagating errors in the production builds? So everything works fine in dev, but when I run the production server and throw an error in a server action I am met with this error in the error boundary: "An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error."
    This happens both for client components and server components calling the same server action. Around 38:00 when you convert the GuestBookEntryForm to a client component and are able to propagate the errors to the client, I see you are running pnpm dev but did it also work on the production build? Sorry for the text wall - was a tricky one to articulate

    • @hamedbahram
      @hamedbahram  Рік тому +1

      The error message you're seeing in production is intentional and how error boundaries work in the app router. Regarding server actions, if you're returning the error instead of throwing it you should be able to handle it client-side.

    • @Neruu2-g3g
      @Neruu2-g3g Рік тому +1

      @@hamedbahram Same issue here.
      I've tried throw and return and both rendered the same digest message.
      At the moment the solution I'm using is returning json object containing my response (created a custom ServerResponse kind of like the NextResponse but containing a success, message, code, ... ), but don't know if that is actually best practice here.

    • @hamedbahram
      @hamedbahram  Рік тому +1

      @@Neruu2-g3g That's a valid way of digesting your errors for sure.

    • @Neruu2-g3g
      @Neruu2-g3g Рік тому +1

      @@hamedbahram thanks!

    • @gustavoseabra7495
      @gustavoseabra7495 Рік тому +1

      ​@@hamedbahram Hello Hamed, I'm experiencing the same issue. I've created a custom error class for cases of unauthenticated users, and in the catch block, if the response status is 401, I throw this error. In client-side pages, I get the expected result, but in server-side pages, I encounter the same problem as they mentioned above (in production). Do you suggest a better way to handle this in server components? . Sorry if my question is repetitive.

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

    Thanks for great explanation!!
    I have a question though.
    I got that server-action runs independently of JS but i woner that if execution of server-action starts until after hydration is done. Or even execution of server-action(ex. asynchronous fetch logic or sth) runs also independently of hydration?
    The reason i m curious about this is at the end of the video, u said server-action is queued until hydration being done

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

      If your form is a client component, then the server action execution is cued until after the hydration. But if you form is also server side then server actions can be immediately executed.

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

      @@hamedbahram wow thx for replying@!! It's interesting execution of server-action when to starts depends on where the form tag is(client or server component🫢)
      Thank u so much:))

  • @ChandanJal-p6h
    @ChandanJal-p6h 10 місяців тому +1

    Hi Hamed,
    I'm just wondering you are throwing the error from the server action.
    How can we handle that ?

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

      Watch the error handing section :)

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

    How would you lay out the structure for adding a delete button for each todo? In terms of a server action that calls a db function for that and passing it to the button, or which way would you prefer to set that up? Thanks in advance.

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

      You can use a `formAction` prop on the button, or wrap the button in a form with the `action` prop. Both would do the same thing.

  • @alvinacosta2312
    @alvinacosta2312 Рік тому +1

    how to change route after adding a guest? if for example my guest list and add form are on separate pages? thanks!!

    • @hamedbahram
      @hamedbahram  Рік тому

      You can call the `redirect` function from `next/navigation` to change routes.

  • @ahmedhassan_saver
    @ahmedhassan_saver Рік тому +1

    Thanks very much
    Can you share notion link

    • @hamedbahram
      @hamedbahram  Рік тому

      You're welcome. I recommend using the docs as a reference. The notion page is just a summary. You can find all the examples in the docs.

  • @gustavoseabra7495
    @gustavoseabra7495 Рік тому +1

    Hi Hamed!
    I have a server page with two components that fetch independently, if an error occurs in the fetch of one component and the other manages to get the data normally, I would like only the component with the error to display the error and the reset opportunity. If both have fetch error i want to show the error independently and each one have their own reset. Is it possible? I still haven't come up with a good solution

    • @hamedbahram
      @hamedbahram  Рік тому +1

      You have wrap each component with separate error boundaries. You can use the `react-error-boundary` package for that.

  • @mohammadheydari9400
    @mohammadheydari9400 Рік тому +1

    Thanks for your video.
    I have a question about how secure is to use server action in client components. If i protect a client page using NextAuth, is there any way someone access to server actions that can be called from that page?

    • @hamedbahram
      @hamedbahram  Рік тому +1

      Good question! I wouldn't recommend server actions for production yet. But generally speaking once stable, it would be safe to pass server actions to the client. I'd recommend defining your actions in a separate file marked with 'use server' and use a middleware to intercept requests for authentication.

  • @liketocode
    @liketocode Рік тому

    Hi Hamed. Great video. When handling local errors, though you do not define the server action in the client component, at 35:50 , the defined client function is asynchronous, so as to await the response of the server action addEntry(), and this produces a React runtime error:
    `Unhandled Runtime Error
    Error: async/await is not yet supported in Client Components.`

    • @hamedbahram
      @hamedbahram  Рік тому

      The error you're receiving is likely because you have turned your client component into an async component (function). Defining an async client-side action (function) won't cause an error.

    • @liketocode
      @liketocode Рік тому

      My client component (function) is not async: 'export default function Form(){...}'. The error message itself says 'async/await inside a client component is not supported'?

    • @hamedbahram
      @hamedbahram  Рік тому

      @@liketocode Hmm 🤔can you clone my code and confirm that you're still getting the same error?

  • @abbaskareem5281
    @abbaskareem5281 Рік тому +1

    pardon me for this question if it's sound silly, server action is mutate data on server what if the server is a django-rest-framework server ? I mean another server not next js node server . I hope you understand what I mean. and thank you sir.

    • @hamedbahram
      @hamedbahram  Рік тому

      Anytime man, that's a good question. With a different backend server, you'd have to use route handlers (API endpoints). You won't be able to use server actions.

    • @brunocascio
      @brunocascio Рік тому +1

      @@hamedbahram Why not? in the server action you can just call other backends... It's like a BFF approach

    • @hamedbahram
      @hamedbahram  Рік тому

      @@brunocascio That's right you can call other backends from your server action. However I think the question was not using the server on NextJs - rather using the django backend.

  • @camembertsucreausucre3440
    @camembertsucreausucre3440 Рік тому +1

    why you dont use server component for the form ?

    • @hamedbahram
      @hamedbahram  Рік тому

      You can definitely use a server component for the form.

    • @camembertsucreausucre3440
      @camembertsucreausucre3440 Рік тому +1

      @@hamedbahram Ok thank you, is it better to validate first on the client side, and if zod doesn't find an error, then run our server action ?

    • @hamedbahram
      @hamedbahram  Рік тому +1

      @@camembertsucreausucre3440 Absolutely!

  • @imkir4n
    @imkir4n Рік тому +1

    😃

  • @tomaslanda1317
    @tomaslanda1317 Рік тому +1

    So server actions will replace swr or reactQuery?

    • @hamedbahram
      @hamedbahram  Рік тому +1

      Yes if you were using those to mutate data :) also the fact that we can now fetch data on the server, reduces the need for those packages on the client.

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

    Setting a cookie on server actions doesnt work. Its only working on middlewares and route handlers. Thats what I understand by testing it. I can only read the cookies on server actions.
    I was trying to refresh session token on server actions, tried everything but none is worked

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

      Did you use the `cookies` function from `next/headers`? example ↓
      ```
      'use server'
      import { cookies } from 'next/headers'
      export async function exampleAction() {
      // Set cookie
      cookies().set('token', '123')
      }
      ```

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

      @@hamedbahram yes I did, im using seperate backend, sending request from server action then trying to update cookies by using the response data.Maybe it's related to seperate backend ?

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

      @@usamecoban2582 Hmm 🤔so is it that you can't see the cookie you're settng in the server action in your separate backend?

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

      @@hamedbahram No, just getting an error (Error: Cookies can only be modified in a Server Action or Route Handler.) when I try to update cookies. Imagine that you have a method in actions.ts file marked as "use server" at the top of the file. If I call this method from server components it fails, but if its called from client components it works. its not server actions anymore when its called from server components. That's what I understand from this test
      My case was sending a request to my seperate backend using server actions. If the response has set-cookie header, i just want to update cookies. But it seems like after response is received its not server actions anymore.

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

      @@usamecoban2582 How are you calling the server action from your server component?

  • @samislam2746
    @samislam2746 7 місяців тому

    I tried to send a POST request using Postman to my server action, in the browser it works, but in postman it doesn't, it just replies back with the HTML, and my console.log() message is not being printed in the terminal as if there is No POST request was sent. why is this?

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

      It's meant to only work through your frontend in the browser.

    • @samislam2746
      @samislam2746 7 місяців тому +1

      @@hamedbahram
      I discovered how. It sends an id and some other arguments as form data in the request headers.

  • @ClarkHilll
    @ClarkHilll Рік тому

    *PromoSM*

  • @hofimastah
    @hofimastah Рік тому +2

    const { error: zodError } = GuestEntrySchema.safeParse({ name, message })
    gives me
    Property 'error' does not exist on type 'SafeParseReturnType'.ts(2339)

    • @hamedbahram
      @hamedbahram  Рік тому +1

      Try the following, this should solve the problem:
      ```
      const result = GuestEntrySchema.safeParse({ name, message })
      if (result.success === false) {
      result.error
      }
      ```

    • @hofimastah
      @hofimastah Рік тому +1

      @@hamedbahram many thanks!

    • @hamedbahram
      @hamedbahram  Рік тому

      @@hofimastah You're welcome.