When should I Use Server Action (Next.js 14)

Yohan LBYohan LB
Oct 17, 2024
6 min read

When I started working on my GeoQuiz App, I started experimenting with the new Next Server Actions. And probably like many of us, I quickly learned to love it, they felt like a clean and efficient solution for most of my server requests.

But as I started to play with it and implement them more, I started noticing I was introducing performance issues, unnecessary round trips between the client and the server and even some dangerous API security issues.

I quickly learned that Server Actions weren't always the most efficient choice, especially for straightforward data fetching.

So let鈥檚 dive in. In the next few paragraphs, I'll take you through the different use cases for Server Actions and show you how they can be a game changer in your Next.js app, especially when used in the right context.

A - What are Server Actions:

Server Actions (soon to be renamed Server Functions in React 19 btw.) are a relatively new feature introduced by React to simplify data handling and move more logic to the server-side. And Next.js has quickly incorporated it with their own twist in Next 14, offering a good complementarity with Server Side Components.

In the following lines, we will focus only on the Next.js implementation.

B - When to use Server Actions

1. Event handling / Performing Database Mutations

Server actions allow you to perform server operations and database mutations securely without exposing database logic or credentials to the client. They drastically reduces and simplify your code because it removes the need to write a specific API route for your operations.

'use server';
export async function handleServerEvent(eventData: any) {
  // Process any server event
  const res = await someAsyncOperation(eventData);
  if (!res.ok) {
    throw new Error('Failed to handle event');
  }  
  return { res, message: 'Server event handled successfully' };
}

2. Handling form submissions

Similar to the first point, but Server Actions are particularly useful for processing form inputs that need server-side handling. They provide a straightforward way to handle form data on the server ensuring data validation and integrity without exposing the logic to the client, and without having to implement elaborate API endpoints.

'use server';
export async function handleFormSubmit(formData: FormData) {
  const name = formData.get('name') as string;
  const email = formData.get('email') as string;
  const message = formData.get('message') as string;
  // Process the form data

  const res = await saveToDatabase({ name, email, message });
  if (!res.ok) {
    throw new Error('Failed to process the form data');
  }  
  return { res, message: 'Form submitted successfully' };
}

3. Fetching data from client components.

Server Actions can also be useful for quick data fetching, where a clean developer experience (DX) is crucial. It can simplify the fetch process by tying data access directly to a component without the need for intermediary API layers. Moreover, when using TypeScript, Server Actions make using types seamless because everything is within the same function boundary.

// Simple server action to fetch data from an API
'use server';

export async function fetchData() {
  const res = await fetch('https://api.example.com/data');
  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }
  return res.json();
}

Working with Next.js and its server component, you already have this very practical way of using server side code to fetch data and pre render your pages on the server.

But Server Action now introduces a brand new way to also do that from your client side components! It can simplify the fetch process by tying data access directly to the component that needs it, without the need for using useEffects hooks or client-side data fetching libraries.

Moreover, when using TypeScript, Server Actions make typing seamless because everything is within the same function boundary, providing overall a great developer experience.

馃挕
However, as we will see in the next section, not every data fetching scenario should leverage server actions, and this solution should be used with some important considerations in mind.

C - Potential Pitfalls with Server Actions

1. Don鈥檛 use server actions from your server side components

The simplicity and great DX of Server Actions could make it tempting to use them everywhere, including from a server side component, and it would work! However, it doesn't really make any sense. Indeed, since your code is already running on the server, you already have the means to fetch anything you need and provide it to your page as props. Using Server Actions here would delay data availability as it causes extra network requests.

For client-side fetching, Server Actions might also not be the best option. First of all, they always automatically use POST requests, and so they cannot be cached automatically like with a GET request. Secondly, if your app needs advanced client side caching and state management, using tools like TanStack Query (React Query) or SWR is going to be way more effective for that. However, I haven鈥檛 tested it myself yet, but it鈥檚 apparently possible to combine both and use TanStack Query to call your server actions directly.

2. Server Actions Do Not Hide Requests!

Be extremely careful when using server actions for sensitive data. Server Actions do not hide or secure your API requests. Even though Server Actions handle server-side logic, under the hood they are just another API Route and POST requests handled automatically by NextJs.

Anyone can replicate them by using a Rest Client, making it essential to validate each request and authenticate users appropriately. If there鈥檚 sensitive logic involved, ensure you have proper authentication and authorization checks within your Server Actions.

馃挕
Additionally, consider using the very popular next-safe-actions package, which can help secure your actions and also provide type safety.

3. Every Action Adds Server Load

Using Server Actions might feel convenient, but every action comes at a cost. The more you offload onto the server, the greater the demand on server resources. You may inadvertently increase your app's latency or cloud costs by using Server Actions when client-side processing would suffice. Lightweight operations that could easily run on the client, like formatting dates, sorting data, or managing small UI state transitions, should stay client-side to keep your server load minimal.

4. Classic API Routes Might Be More Appropriate

There are cases where sticking with traditional API routes makes more sense, particularly when you need your API to be accessible to multiple clients. Imagine if you need the same logic for both your web app and a mobile app, duplicating the same Server Action logic into an API route will only double the work and maintenance. In these situations, having a centralized API route that all clients can call is a better solution, as it avoids redundancy and ensures consistency across your different clients.

5. Next.js Dependency and the Moving Target

It鈥檚 important to note that Server Actions are closely integrated with Next.js, and both Next.js and React are evolving rapidly. This pace of development can introduce compatibility issues or breaking changes as these frameworks continue to update. If your application prioritizes stability and long-term support, relying heavily on cutting-edge features like Server Actions could result in unwanted technical debt. Weighing the stability of traditional, well-established methods against the appeal of new features is always advisable.

Conclusion

Server Actions in Next.js 14 can be a powerful addition to your toolkit, but like any new tool, they come with trade-offs. Used in the right context, such as server event handling, form submissions, and specific internal data fetching, they can simplify your code and improve your developer experience.

However, be mindful of their limitations: the lack of native caching, the server cost implications, and the security issues. By considering these factors, you can decide when it makes sense to leverage Server Actions and when traditional methods might serve you better.

Let me know what you think! Can you think of more use cases? What is your personal usage of using server actions?

51
Subscribe to my newsletter

Read articles from Yohan LB directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yohan LB
Yohan LB

Currently working on GeoQuiz.co !