Introduction

It’s possible that within a client component there should be a child component that needs to be a server component. Luckily there is a way to turn a client component back to a server component and I’m gonna show in this article, how to achieve just that.


The use server tag

Not only is there a tag for forcing a component to be a client component, but there is also one for making a component a server component. When adding the tag β€œuse server”, my component will become again a sever component. However I learnd that the β€œuse sever” tag is only applicable for functions.


Create a Server Action

src/features/ticket/actions/delete-ticket.ts

The deleteTicket is called form the TicketItem component. Since TicketItem is a client component, the deleteTicket function would become by default also a client component. But since I have to access the database when deleting a ticket, I need to convert the function back to a server component.

"use server";
 
import { redirect } from "next/navigation";
import prisma from "@/lib/prisma";
import { ticketsPath } from "@/paths";
 
export const deleteTicket = async (id: string) => {
  await prisma.ticket.delete({
    where: {
      id,
    },
  });
  redirect(ticketsPath());
};

Implement in a Server Component

In order to access a server action from a server component, I need to use a form, else I can’t pass a param.

const AppProjectCard = ({ project }: ProjectCardProps) => {
 
  const deleteButton = (
    <form action={deleteTicket.bind(null, project.id)}>
      <Button variant="outline" size="icon">
        <LucideTrash className="h-4 w-4" />
      </Button>
    </form>
  );
 
  return (
    <div>{deleteButton}</div>
)

Implement in a Client Component

It’s easier to access the server action from a client component, I can simply do it like that:

  const handleDeleteTicket = async () => {
    await deleteTicket(ticket.id);
  };

Conclusion

It’s good to know that turning a component into a client component isn’t a one way route but can be redone again. Definitely useful for buttons and co that need to be able to communicate with the server even though they are in a client component. I think it’s also good that there is no need for turning the full UI component into a server component, instead I can only apply this change to a single button component.