Server Actions
Learn how to write a server action in your Next.js Supabase SaaS application
Makerkit makes extensive use of Next.js Server Actions to mutate data in your Supabase database.
Server Actions are a powerful feature of Next.js that allow you to write server-side code that we can call from the client-side. This is useful for a number of reasons:
- We don't need to write any API routes to handle our server-side logic
- We can tell Next.js to revalidate our data after a server action has been called, thus refreshing our data on the client-side
- We can easily call them just like any other function in our code
This page is important to explain how we can handle Supabase mutations in the next sections.
Creating a Server Action
To create a server action, we need to create a separate file marked with the use server
directive at the top of the file. This tells Next.js that this file contains a server action that we can call from the client-side.
'use server';export async function handleFormSubmit( formData: FormData) { // Do something with the form data}
Calling a Server Action
Calling a server action can be done in several ways
- Calling it from a form submit handler
- Calling it from a button click handler
- Calling it imperatively as a function
Calling it from a form submit handler
Let's assume we defined our server actions in a file called actions.ts
:
'use server';export async function createPostAction( formData: FormData) { // Do something with the form data}
We can call this server action from a form submit handler like so:
<form action={createPostAction}> <div className='flex flex-col space-y-4'> <h2 className='text-lg font-semibold'>Create a new Post</h2> <Label className='flex flex-col space-y-1.5'> <span>Title</span> <Input name='title' placeholder='Ex. The best Next.js libraries' required /> </Label> <Label className='flex flex-col space-y-1.5'> <span>Description</span> <Input /> </Label> <SubmitButton /> </div></form>
Calling it from a button click handler
We can also call a server action from a button click handler:
<form action={createPostAction}> <div className='flex flex-col space-y-4'> <h2 className='text-lg font-semibold'>Create a new Post</h2> <Label className='flex flex-col space-y-1.5'> <span>Title</span> <Input name='title' placeholder='Ex. The best Next.js libraries' required /> </Label> <Label className='flex flex-col space-y-1.5'> <span>Description</span> <Input /> </Label> <button formAction={createPostAction}>Click</button> </div></form>
Calling it imperatively as a function
Finally, we can call a server action imperatively as a function using startTransition
:
import { useTransition } from "react";function ClientComponent({ id }) { let [isPending, startTransition] = useTransition(); return ( <button onClick={() => startTransition(() => createPostAction(id))}> Save </button> );}
Send CSRF token with server actions
Remember: Makerkit protects by default every POST request with a CSRF token. This is a security measure to prevent CSRF attacks.
It's your job to send this along when you call a server action.