The Power of Next.js Server Actions: Simplicity Flexibility and Organization

At Arcus Digital, we are always looking for new tools that facilitate faster iteration and eliminate unnecessary complexity in our projects. Most recently this ethos has led us to embrace Server Actions in our Next.js projects. In this blog post, we will delve into the ways this innovative tool has elevated our workflow, with a focus on its simplicity, flexibility, and organizational benefits.

Simplicity

Next.js Server Actions offer an elegant solution for implementing server-side logic. Previously, for any data mutation requiring credentials, we would set up an API route. Then we would implement a form that, upon submission, would post to that route, which then interacted with the database. With Server Actions, we can now streamline this process by writing a function marked as "use server" within the component (or more often within the component's directory in a separate file), no http request required.

// components/some-component/actions.ts

"use server"
export const myServerAction = async (postData: string) => {
  // Server-side logic with postData and credentials stored on the server
  return someData;
};

// components/some-component/index.ts

"use client"
import { myServerAction } from "./actions.ts"
import { useState } from "react";

export default function MyComponent(){
  const [data, setData] = useState('');
 
  const postData = async () => {
    try {
      const result = await myServerAction(data);
      console.log("Posted Data Successfully:", result);
    } catch (error) {
      console.error("Error posting data:", error.message);
    }
  };

  return (
    <div>
      <input
        type="text"
        onChange={(e) => setData(e.target.value)}
      />
      <button onClick={()=>postData}>Post Data</button>
    </div>
  );
};






Flexibility

As demonstrated in the code snippet above, server actions, when declared in a 'use server' file, can be seamlessly imported directly into client components. This pattern has significantly enhanced our workflows, enabling versatile usage for data fetching, computations, and even authentication and authorization. The flexibility of this pattern has allowed us to encapsulate our server-side logic into dedicated action files. These files can then be effortlessly reused across different components, effectively minimizing code repetition and fostering a faster iteration cycle.

Organization

By shifting our server-side logic out of a dedicated API directory, we've gained the flexibility to place it exactly where it makes the most sense. Take a cart component in an e-commerce website, for instance, composed of several sub-components. Now, we can create an action file right in the root of the cart directory. This approach ensures that all the server-side logic for a specific component is neatly organized in one logical place. No more developers spending hours searching for the right API route—it's all right where you'd expect it. This not only enhances clarity but also boosts efficiency in our development team.

Conclusion

Despite a small initial learning curve, Next.js server actions have been a big win for our team. They have allowed us to get to a viable product more quickly, and iterate with our stake holders faster. The end result is happier developers and more satisfied clients. Cant beat that.