DEV Community

Nelson chege
Nelson chege

Posted on • Edited on

working with Server Actions

Server actions were introduced in NextJs version 13.4 in Alpha together with turbopack (Beta) and App router(stable).

They have a good developer Experience when using them plus other features that are really nice to have.

with server actions:

  • allows progressive Enhancement which allows forms to function correctly without javascript
  • you can now you forms inside of server action, reducing the amount of javascript shipped to the client
  • you don't need to create other endpoints todo mutations. (but these actions are considered as api endpoints by nextjs)

Because at the moment,server Actions is still in Alpha, you have to add this to your next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverActions: true,
  },
};

module.exports = nextConfig;
Enter fullscreen mode Exit fullscreen mode

now creating a simple form that calls an action

import { addTodo } from "../lib/actions";
const AddTodo = () => {
  return (
    <div>
      <form action={addTodo}>
        <div className="">
          <input
            type="text"
            name="todo"
            required
          />
        </div>
        <div>
          <button
            type="submit"
           >
            Submit
          </button>
        </div>
      </form>
    </div>
  );
};

export default AddTodo;
Enter fullscreen mode Exit fullscreen mode

server actions can be imported and saved in a separate file making them cool to work with.

the "use server" must be included on top of the file

"use server";

import { randomUUID } from "crypto";
import { revalidatePath } from "next/cache";

export async function addTodo(data: FormData) {
  const todo = data.get("todo");

  await fetch("http://localhost:3500/todos", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      todo,
      userId: randomUUID,
    }),
  });

  revalidatePath("/");
}
Enter fullscreen mode Exit fullscreen mode

inside the Action you are able to do all the things that a normal API endpoint used to handle such as communicating to a database

the revalidatePath will update the cache with the new data add to the specified path.

And thats all required to get started using server actions.

An extra feature that can be included inside server action is the useTransition hook.
This provides pending and startTransitions to play around with. you can disable the button using the pending status.

"use client";

import React, { useRef, useTransition } from "react";

type AddTodoFormProps = { addTodo: (todo: string) => Promise<void> };

const AddTodoForm = ({ addTodo }: AddTodoFormProps) => {
  const todoRef = useRef<HTMLInputElement>(null);
  let [pending, startTransition] = useTransition();
  return (
    <>
      <div className="">
        <input
          ref={todoRef}
          type="text"
          id="todo"
          name="todo"
          required
        />
      </div>
      <div>
        <button
          disabled={pending}
          onClick={async () => {
            startTransition(async () => {
              await addTodo(todoRef.current!.value);
            });
          }}
        >
          Submit
        </button>
      </div>
    </>
  );
};

export default AddTodoForm;
Enter fullscreen mode Exit fullscreen mode

for the action, data passed to the action will only be that one variable

"use server";

import { randomUUID } from "crypto";
import { revalidatePath } from "next/cache";

export async function addTodo(data: string) {
  const todo = data;
  const payload = {
    todo,
    userId: randomUUID(),
    createdAt: new Date(new Date()).toLocaleString(),
  };

  await fetch("http://localhost:3500/todos", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  });

  revalidatePath("/");
}
Enter fullscreen mode Exit fullscreen mode

conclusion

server actions is an easier way to communicate with your backend without extra endpoints and also reduce the javascript code that is passed to the client side.

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay