Next.js Data Fetching and Errror handling
Various ways to fetch data and handle errors in a next.js app
I have been building web applications with Next.js for some time now. When I first started using Next.js (version 14), there were lots of different ways to do the same thing. There are lots of articles and YouTube videos on Next.js, but I think the information is a bit fragmented. So, after spending time learning about all the possible ways to handle data fetching and error handling, here are my 2 cents on what options are available, and you can decide on your own which pattern to pick for your application.
Server Action + server data loader
This might be the simplest and most straight forward way of GET
and POST data
Breakdown:
Just create an async function to fetch the data you want to fetch. You can use third-party APIs or connect to your DB directly.
Invoke the async function in the server component directly.
Either display the data or handle errors.
Breakdown:
Create a server action (PUT, POST, DELETE).
Create a form with all the necessary form field elements.
Use
zod
or something similar to handle client-side and server-side validation. (I only show you the server-side validations, but client-side validation is pretty similar, and there are many ways you can do it with different form libraries. I might make another post on this topic alone.)Use
useFormState
(this API is subject to change and might be called differently in React 19) to get errors from server actions and also previously submitted states to repopulate form fields for a better user experience.The last step is to either display the errors or show a success toast and redirect, which is completely up to you.
Route Handlers (
GET, POST, PUT, DELETE)
Breakdown:
Create an API route for the resources you want to create/update/delete.
Call those APIs in client components like you normally would.
The most important part about this pattern is that the route handler returns the correct response and status, and the client side handles them correctly.
These are the most common ways I use when it comes to data fetching and error handling when building Next.js applications. Of course, there are many different ways you can mix and match:
Use route handler + server actions.
Use optimistic update + server actions (like a post or something like that).
Use client-side validation mainly (server still validates, but you don't have to use APIs like
useFormState
).
That's all for now. If you know any patterns I didn't mention or you feel that I am doing something wrong, feel free to correct me in the comment section. I would love to learn more about how to effectively use Next.js to build applications.
Until next time, take care!