See the clap count at the bottom left ↙? That’s Claps. In this tutorial, we will understand Server Actions and build a similar component for your app together. Feel free to jump to Project Setup if you want to go ahead with the implementation.
You can also use our open source component @upstash/claps. Easy to setup, nothing to maintain and completely serverless.
Understanding Server Actions
Server Actions are async functions that are executed on the server. They allow you to define server-side functions directly in your components. They can be invoked from the client side without explicitly defining API routes or handling network requests manually.
Server Actions can be used in both Client Components and Server Components. In the following sections, we will design our Claps component firstly as a Client Component and then as a Server Component, to see how Server Actions work in each case and compare the two approaches. Finally, we will implement one of these designs.
'use server'
Directive
‘use server’
directive is used to mark Server Actions. Server Actions are commonly confused with React Server Components. Checkout our blog post Working with React Server Components if you are not familiar with them to better understand the distinction.
Working with Client Components
Now let’s design our Claps component as a Client Component.
- Client Components can only import actions from files that use the
'use server'
directive:
- Now
getClapCount
can be used to retrieve the number of claps andclap
can be used to increase it."use client"
declares a boundary between Server and Client Component modules, making this a Client Component.
Behind the Scenes
While Claps
is being built, bundler will create references to getClapCount
and clap
Server Actions in the bundle. When the useEffect
runs or button
is clicked, React will send a request to the server to execute the corresponding function using these references.
Working with Server Components
Now let’s design our Claps component as a Server Component.
- Server Actions be defined in Server Components with the
‘use server’
directive. Next.js uses Server Components by default, making this a Server Component.
- Event handlers such as
onClick
cannot be used in Server Components. Therefore we need to separate theButton
as a Client Component and pass theclap
Server Action down to it.
Behind the Scenes
While Claps
is being rendered, React will create a reference to clap
Server Action and pass it to the Button
. When the button
is clicked, React will send a request to the server to execute the clap
using this reference.
Choosing an Approach
As shown in the design with Client Components, you can also use Server Actions to fetch data. However, this is discouraged since actions only use the POST
method. For this case, fetching the data in React Server Components and passing it down as props seems to be a better design. Moreover, this approach provides a unified simple view of the component and displays the data on first render instead of using useEffect
.
Server Actions in Next.js and Security
Server Actions are basically publicly accessible HTTP endpoints that only use the POST
method. Even if they are not imported elsewhere in your code they are public, you should treat them as such and secure them. For more information on Server Actions Security you can check the Next.js documentation.
- Authentication and Authorization: You should always check if the user is allowed to invoke this action.
- Validating Arguments: Keep in mind that TypeScript annotations you provide to the function are not not enforced, you should manually validate the types of arguments or use a tool like
zod
. - Closures: When you define a Server Action inside a component, a closure is created so that the action has access to outer function’s scope. Variables in the outer function’s scope may contain sensitive data, so Next.js encrypts them with a private key that is created for each action and for each build.
Next.js recommends using React taint APIs to prevent specific data from being exposed to the client.
Next.js 15 RC 2 also introduced some enhancements to improve the security of Server Actions:
- Dead Code Elimination: IDs of unused Server Actions won’t be exposed.
- Secure Action IDs: Unguessable IDs are created periodically between builds.
Project Setup
We will use a Blog template from Vercel:
You can run the example locally and see what it looks like:
Let’s install @upstash/redis
:
Environment Setup
- Go to Upstash Console → Redis and create a new Database:
- Scroll down to REST API section, switch to .env tab and copy the environment variables for the next step:
- Create a
.env
file and paste your environment variables:
Implementation
Create Claps Component with a Server Action
Create /app/components/claps.tsx
:
We are using revalidatePath
at the end of the clap
Server Action to purge the cached data so that we can see the updated number of claps.
Create the Button Component
Create /app/components/button.tsx
:
We are separating the Button
as a Client Component here so that we can use onClick
with the reference of clap
Server Action passed down from Claps
Server Component.
Import and Display Claps Component
Edit /app/blog/[slug]/page.tsx
:
Visit http://localhost:3000/blog/vim to see the claps in action:
Deploy
You can deploy your site to Vercel with the following command:
Final Words
Using Server Actions removed the necessity of a separate API and provided a simple view of the component and its logic. I hope this guide helps you further simplify your codebase and improve your development experience.