Server Actions adalah fungsi asinkron yang berjalan di server, ditandai directive
`"use server"`, dan bisa dipanggil langsung dari form atau event handler di
komponen React tanpa membuat endpoint API terpisah. Next.js App Router
menjadikannya cara default untuk menangani mutasi data (create, update, delete)
sejak Next.js 14, dan sudah terintegrasi penuh dengan hook baru React 19 seperti
`useActionState`.

**Ringkasan cepat:**

1. Server Actions dibuat dengan directive `"use server"`, di dalam fungsi terpisah atau langsung di dalam file Server Component.
2. Dipanggil lewat atribut `action` pada elemen `<form>`, sehingga form tetap berfungsi progresif meski JavaScript belum termuat.
3. `useActionState` (React 19) menyatukan state hasil, status pending, dan argumen sebelumnya dalam satu hook untuk form yang butuh feedback UI.
4. Server Actions bukan pengganti total Route Handler API — endpoint publik untuk pihak ketiga tetap butuh `route.ts`.
5. Validasi dan otorisasi tetap wajib ditulis di dalam action itu sendiri, sama seperti endpoint API biasa.

## Apa Itu Server Actions dan Bagaimana Cara Kerjanya?

Server Actions adalah bentuk khusus dari React Server Functions: fungsi asinkron
bertanda `"use server"` yang kodenya hanya pernah dieksekusi di server, tidak
pernah dikirim ke bundle JavaScript client. Menurut [dokumentasi resmi Next.js](https://nextjs.org/docs/app/getting-started/mutating-data),
Server Actions dipanggil lewat mekanisme action React seperti `<form action>`,
`<button formAction>`, atau transisi client (`startTransition`) yang memicu
event handler.

```ts
// app/actions.ts
"use server";

export async function createPost(formData: FormData) {
  const title = formData.get("title");
  // Validasi + tulis ke database di sini
}
```

Directive `"use server"` bisa ditulis di baris pertama file terpisah (semua
fungsi di file itu otomatis jadi Server Action) atau langsung di awal badan
fungsi async di dalam Server Component. Next.js membungkus pemanggilannya lewat
`POST` request internal, tapi developer tidak perlu menulis endpoint itu
sendiri.

### Kenapa Validasi Ulang di Server Tetap Wajib?

Server Action yang diekspor otomatis menjadi endpoint yang bisa dipanggil
langsung lewat request `POST`, bukan cuma lewat UI form yang terlihat di
halaman. [Dokumentasi resmi Next.js](https://nextjs.org/docs/app/getting-started/mutating-data#what-are-server-functions)
menegaskan hal ini secara eksplisit sebagai alasan kenapa autentikasi dan
otorisasi harus dicek ulang di dalam setiap Server Function, bukan
diasumsikan sudah ditangani lebih dulu oleh UI:

> Server Functions are reachable via direct POST requests, not just
> through your application's UI. Always verify authentication and
> authorization inside every Server Function.
>
> — [Dokumentasi Next.js: Mutating Data](https://nextjs.org/docs/app/getting-started/mutating-data#what-are-server-functions)

### Kenapa Bisa Dipanggil Langsung dari Form?

Karena atribut `action` pada elemen `<form>` HTML native menerima fungsi di
React 19, bukan cuma string URL. Saat form disubmit, React mengirim `FormData`
ke Server Action yang direferensikan, dan browser tetap bisa submit form itu
meski JavaScript belum selesai dimuat (progressive enhancement) — form akan
melakukan navigasi standar sebagai fallback, baru diambil alih React setelah
hydration selesai.

Progressive enhancement ini bukan sekadar detail teknis kecil. Riset
[Government Digital Service Inggris](https://gds.blog.gov.uk/2013/10/21/how-many-people-are-missing-out-on-javascript-enhancement/)
menemukan 1,1% pengguna (sekitar 1 dari 93 orang) tidak mendapatkan
enhancement JavaScript sama sekali: 0,2% memakai browser yang memang
menonaktifkan atau tidak mendukung JavaScript, dan 0,9% lagi punya
JavaScript aktif tapi gagal termuat di sisi mereka karena pemblokiran
korporat, error browser, atau koneksi tidak stabil. Form yang dibangun
lewat atribut `action` Server Actions tetap berfungsi untuk kelompok ini
karena submit-nya jatuh ke navigasi HTML standar, bukan bergantung pada
JavaScript yang berhasil dieksekusi.

> 1.1% of people aren't getting JavaScript enhancements. This includes
> 0.2% of all people's browsers who have disabled, or don't support,
> JavaScript and 0.9% of all people's browsers have JavaScript enabled
> but don't receive it.
>
> — [Government Digital Service Inggris](https://gds.blog.gov.uk/2013/10/21/how-many-people-are-missing-out-on-javascript-enhancement/)

## Bagaimana Cara Memakai useActionState untuk Form dengan Status Pending?

`useActionState` adalah hook React 19 yang dirancang khusus untuk menyambungkan
UI form ke Server Action, menggantikan pola lama yang biasanya menggabungkan
`useState` + `useTransition` secara manual untuk melacak status submit.

```tsx
"use client";

import { useActionState } from "react";
import { createPost } from "./actions";

const initialState = { message: "" };

export function PostForm() {
  const [state, formAction, isPending] = useActionState(
    createPost,
    initialState
  );

  return (
    <form action={formAction}>
      <input name="title" required />
      <button type="submit" disabled={isPending}>
        {isPending ? "Menyimpan..." : "Simpan"}
      </button>
      {state.message && <p>{state.message}</p>}
    </form>
  );
}
```

Hook ini mengembalikan tiga nilai: `state` (hasil terakhir dari action,
termasuk pesan error/sukses yang di-return manual dari dalam Server Action),
`formAction` (fungsi yang dipasang ke atribut `action` form), dan `isPending`
(status submit sedang berjalan atau tidak) — semuanya tersinkron otomatis
tanpa state tambahan.

### Kapan Server Actions Tidak Cocok Dipakai?

Server Actions dirancang untuk mutasi data internal aplikasi sendiri, bukan
pengganti universal untuk Route Handler API. Situasi yang tetap butuh
`app/api/.../route.ts` biasa: endpoint yang diakses langsung oleh sistem pihak
ketiga (webhook payment gateway, integrasi eksternal), respons non-HTML seperti
file atau JSON publik yang perlu dikonsumsi di luar aplikasi Next.js itu
sendiri, atau ketika dibutuhkan kontrol penuh atas method HTTP dan header
response.

| Aspek | Server Actions | Route Handler (`route.ts`) | Fetch sisi client |
| --- | --- | --- | --- |
| Method HTTP | Selalu `POST` di balik layar | Bebas: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS` | Tergantung endpoint yang dipanggil |
| Perlu file endpoint terpisah? | Tidak — fungsi langsung terhubung ke `<form action>` | Ya, file `route.ts` sendiri per rute | Perlu endpoint tujuan (Route Handler atau API eksternal) |
| Tetap jalan tanpa JavaScript? | Ya, form submit lewat navigasi HTML standar (progressive enhancement bawaan) | Handler dieksekusi di server, tapi trigger dari UI tetap butuh form/link standar untuk jalan tanpa JS | Tidak — `fetch()` hanya berjalan kalau JavaScript aktif di browser |
| Cocok untuk webhook/konsumen pihak ketiga? | Tidak dirancang untuk ini, endpoint tetap POST internal | Ya, pola resmi Next.js untuk menerima webhook eksternal | Ya kalau target API eksternal, tapi request berasal dari browser pengguna |
| Bisa balas respons non-HTML custom (JSON/XML/file)? | Tidak, dirancang untuk mutasi UI, bukan payload custom | Ya, lewat `Response`/`NextResponse` dengan header dan status code bebas | Tergantung endpoint yang dipanggil, bukan ditentukan cara fetch-nya |

Dasar arsitektur App Router yang mendukung kedua pola ini dibahas
lebih lengkap di [App Router vs Pages Router: kapan pakai yang mana](/blog/app-router-vs-pages-router-nextjs-kapan-pakai).

## Ringkasan: Form Tanpa Endpoint Terpisah, Progressive Enhancement Bawaan, dan Kapan Route Handler Tetap Wajib

- Server Actions adalah fungsi `"use server"` yang berjalan sepenuhnya di server dan dipanggil langsung dari form atau event handler, tanpa endpoint API terpisah.
- `useActionState` (React 19) menyatukan state hasil, status pending, dan argumen sebelumnya dalam satu hook yang otomatis terhubung ke atribut `action` form.
- Server Actions bukan pengganti total Route Handler API — endpoint untuk pihak ketiga atau respons non-HTML tetap butuh `route.ts` biasa.
- Validasi dan otorisasi wajib ditulis di dalam action itu sendiri karena Server Action tetap bisa dipanggil dari mana saja selama endpoint-nya diketahui.
- Server Actions mengoptimasi sisi mutasi data; untuk sisi render, App Router
  punya pendekatan komplementer lewat [React Compiler](/blog/react-compiler-nextjs-panduan-lengkap)
  yang menambahkan memoization otomatis tanpa `useMemo`/`useCallback` manual.
- Setelah mutasi di dalam Server Action selesai, cache Next.js perlu
  disegarkan secara eksplisit — lihat perbandingan
  [revalidatePath vs revalidateTag: Kapan Pakai?](/blog/revalidatepath-vs-revalidatetag-nextjs)
  untuk memilih fungsi yang tepat.
- Contoh penerapan konkret pola-pola di atas (validasi ulang di server,
  honeypot anti-spam, pengiriman email) ada di
  [panduan form kontak Next.js dengan Server Actions](/blog/cara-membuat-form-kontak-nextjs-server-actions).
- Semua contoh kode Server Action di atas ditulis TypeScript, bukan
  kebetulan — lihat [kenapa TypeScript jadi standar developer
  2026](/blog/kenapa-typescript-jadi-standar-developer-2026) untuk data
  survei di balik adopsinya.
- Butuh bantuan implementasi Next.js App Router seperti ini di proyek sendiri? Lihat [layanan web development](/layanan) yang ditawarkan.