フレームワーク プログラミング ソフトウェア 公開日 2026.05.15 更新日 2026.05.15

Server Actions とは何か?Next.js / React で `フォームから関数を直接呼ぶ』 仕組みと API Routes との違い

Server Actions は Next.js / React の新しい仕組みで、`サーバで実行される関数をクライアントから直接呼べる』 機能です。`use server』 宣言とフォームの action 属性を組み合わせて、API Routes を書かずにサーバ処理を呼べるため、フォーム送信や CRUD が大幅にシンプルになります。仕組み、API Routes / tRPC との使い分けを整理します。

先に要点

  • Server ActionsNext.js / React 19 の機能で、` サーバで実行される関数をクライアントから直接呼べる』 仕組み。`use server』 ディレクティブを付けた関数が対象。
  • 典型は ` フォームの `action』 属性に直接サーバ関数を渡す』 書き方。`
    』 でフォーム送信が完結し、API Route を別途書かなくてよい。
  • JavaScript 無効でも動く(プログレッシブエンハンスメント)、` revalidatePath / revalidateTag』 でキャッシュ無効化が自然` useFormStatus / useOptimistic』 で `送信中』 `楽観的更新』 を素直に書ける
  • 使いどころは ` フォーム送信 / CRUD』 が中心。tRPCRSC の `データ取得』 と棲み分け、`書く方は Server Actions、読む方は RSC』 が App Router の標準スタイル

Server Actions って結局何ができるの? API Routes と何が違うの? <form action={...}> に関数を渡せるって本当?』 ── Next.js 14 / 15 で安定化した Server Actions は、フォームと API のあり方』 を大きく変える React の新機能です。

ざっくり言うと、Server Actions は サーバで動く関数を、クライアント側のコードから関数として呼べる』 仕組み</strong> です。 従来fetch('/api/todos', { method: 'POST', ... })』 のように書いていたフォーム送信や CRUD 処理が、` サーバ関数を直接呼ぶ』 形で書けるようになります。

この記事では、2026年5月時点の Next.js 15 系をベースに、Server Actions の仕組み・書き方・API Routes / tRPC との違い・落とし穴 を、`React は触っているけど App Router はこれから』 レベルからでも追える形で整理します。

基本の書き方 — `use server』

最小例で雰囲気をつかみます。

// app/todos/actions.ts
'use server';

import { db } from '@/lib/db';
import { revalidatePath } from 'next/cache';

export async function createTodo(formData: FormData) {
  const title = formData.get('title') as string;
  await db.todo.create({ data: { title } });
  revalidatePath('/todos');
}
// app/todos/page.tsx
import { createTodo } from './actions';

export default function TodosPage() {
  return (
    <form action={createTodo}>
      <input name="title" required />
      <button type="submit">追加</button>
    </form>
  );
}

これだけで、フォームを送信するとcreateTodo』 関数がサーバで実行される』 という挙動が完成します。

`'use server'』

ファイル先頭か関数先頭に書く。`このコードはサーバでだけ動かす』 という宣言。これを書いた関数だけが Server Action として呼べる

`action={...}』

` form の action 属性』 に Server Action を直接渡す。`API Route の URL を文字列で書く』 必要がない。

`FormData』

送信されたフォームの値は `FormData』 として受け取る。`name 属性』 がキーになる。`zod』 で検証してから処理するのがチーム標準的なパターン。

`revalidatePath』

` 関連するページのキャッシュを無効化』 して再生成する。`todo を作ったら todos リストを更新』 が1行で書ける。

API Route + fetch + 状態管理』 のセットを書く代わりに、サーバ関数を直接フォームに渡す』 だけで完結するのが体験を一新する部分です。

JavaScript 無効でも動く — プログレッシブエンハンスメント

Server Actions の地味だが大事な特徴が、` JavaScript が読み込まれていなくてもフォーム送信が動く』 ことです。

仕組み

`

』 は、JS 有効時は `fn(formData)』 を直接実行、JS 無効時は ` 標準の HTML フォーム送信に降格』 し、サーバ側で同じ関数が呼ばれる。

嬉しい場面

` 初回ロード時に JS がまだ来ていない 1〜2秒の間』 でも、フォームが押せれば送信できる。`htmx 的な世界観』 と同じ哲学。

アクセシビリティ

` JS が無効な環境(支援技術、低帯域、企業内ブロック等)』 でも基本動作は維持される。`動かないボタン』 が減る。

SEO / クローラー

サーバが完全に応答するので、`クローラーやリンクプレビュー』 にも安定して見える。

Web の基本に戻る』 哲学を、React のコンポーネント記述スタイル』 に組み込んだのが Server Actions の野心的な部分です。

useFormStatus』 / useOptimistic』 で動的 UI

送信中はボタンを無効化』 楽観的に UI 更新』 のような React らしい書き味も用意されています。

'use client';
import { useFormStatus } from 'react-dom';

export function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? '送信中…' : '追加'}
    </button>
  );
}
'use client';
import { useOptimistic } from 'react';

export function TodoList({ todos }: { todos: Todo[] }) {
  const [optimistic, addOptimistic] = useOptimistic(
    todos,
    (state, newTodo: Todo) => [...state, newTodo]
  );

  async function addAction(formData: FormData) {
    const title = formData.get('title') as string;
    addOptimistic({ id: 'temp', title });
    await createTodo(formData);
  }

  return (
    <>
      <form action={addAction}>...</form>
      <ul>{optimistic.map(t => <li key={t.id}>{t.title}</li>)}</ul>
    </>
  );
}

`useFormStatus』

フォームの送信状態(`pending』 `data』 `method』 `action』)を取得。子コンポーネントから親フォームの状態を見られる ので、`SubmitButton』 を別ファイルに切り出すような設計がしやすい。

`useOptimistic』

` サーバが応答する前に UI を仮更新』 する React 19 のフック。`いいねボタン』 `Todo 追加』 のような `押した瞬間に反映してほしい UX』 を、ロールバック処理を含めて素直に書ける。

`useActionState』

` Server Action の結果を状態として保持』 する。`バリデーションエラーをフォーム横に表示』 のような用途で必須レベル。

Client 側でも呼べる

` Server Action は普通の関数として、Client Component から `onClick』 内で呼ぶこともできる』。`form の action だけ』 ではなく、`関数として呼べる API』 として柔軟に使える。

`プログレッシブエンハンスメントを保ちつつ、リッチな UX も両立する』 のが、Server Actions が React に組み込まれている理由です。

API Routes / tRPC との違い

`Server Actions と他の API 方式、何が違う?』 を表で並べます。

Next.js API Routes tRPC Server Actions
呼び出し方 `fetch(URL, ...)』 `trpc.x.mutate(...)』 関数を直接呼ぶ / form.action
URL 設計 明示的 抽象化される 意識しない(裏で内部 URL に変換)
型安全 自前で保証 ◎(共有型) ◎(関数の型がそのまま)
フォームとの統合 手書き 手書き 標準(`action={fn}』)
JS 無効時の挙動 動かない 動かない 標準フォーム送信に降格
外部から呼ぶ ○(公開 API として運用可) △(クライアント限定が前提) ×(内部利用前提)
主な用途 公開 API / Webhooks TS フルスタックの内部 API フォーム / CRUD / アプリ内処理

要点は 外部公開 API → API Routes、内向き複雑な API → tRPC、フォーム / 内部アクション → Server Actions』</strong> という棲み分けです。 3つは競合ではなく、用途で使い分ける道具立て』 として捉えるのが正解です。

ハマりやすいポイント

便利だが、現場で詰まりやすい注意点もあります。

①セキュリティ

Server Actions は 内部 URL を介して公開される。`関数を import しているだけ』 でも実際には API として叩ける状態になる。認証 / 認可チェックを Action の冒頭で必ず行う のが鉄則。

② 入力検証

` FormData』 は信用できない。Zod で必ず検証。`zod-form-data』 や `useActionState』 とセットで使うのがチーム標準。

③ revalidate の漏れ

` DB を更新したのにキャッシュが古いまま』 が起きやすい。`revalidatePath』 `revalidateTag』 を必ず適切な箇所に入れる。

④ ファイルアップロード

大きなファイルを Server Action で扱うと、`Next.js のリクエストサイズ制限』 にぶつかる。大きいものは `署名付き URL で直接ストレージへ』 のような迂回策が必要。

⑤ エラーハンドリング

` action 内で throw すると 500 になる』。ユーザー向けエラーは `return { error: '...' }』 のようにオブジェクトで返し、`useActionState』 で受けるのが標準パターン。

Edge / Serverless 上限

` Server Action は Edge / Serverless の制約に従う』。`長時間処理』 や `CPU 時間制限』 にぶつからないよう、`重い処理はキュー(Inngest / QStash 等)に逃がす』。

API を書かなくていい』 と聞くと万能に思えるかもしれませんが、<strong> API を書かない代わりに、Action の冒頭で `認証・認可・検証』 を必ずやる規律 が必要、というのが正確な理解です。

いつ Server Actions を選ぶか

採用判断の目安を整理します。

向いている

① 新規 Next.js App Router 案件、② フォーム / CRUD / 内部アクションが中心、③ TypeScript フルスタック、④ チームが Next.js に慣れている。

向かない / 慎重に

① 外部公開 API を作る、② Next.js 以外のクライアント(モバイルアプリ等)から叩く、③ 既存 Pages Router を急いで変える、④ 完全分離 BFF が必要な大規模組織。

tRPC と併用

` 内部の複雑な GET 系は tRPC、フォーム送信は Server Actions』 という併用が現実的。`一つの記事で書ききれない複雑な API 群』 では併用が安定。

RSC との組み合わせ

` 読みは RSC、書きは Server Actions』 が App Router の標準的な構成。`useEffect で fetch』 をほぼ書かなくて済む。

`Next.js App Router を採用したら、Server Actions は自然と使うことになる』 という距離感が現実的です。

AI 時代の Server Actions

AI 連携の文脈でも Server Actions の使いどころは増えています。

AI プロンプト送信

` ユーザー入力 → Server Action → LLM API 呼び出し → ストリーミング応答』 が綺麗に書ける。`API キーがサーバから出ない』 構造を保てる。

useOptimistic との相乗

` AI 応答を待つ間、`...生成中』 と楽観的表示 → 結果が返ったら差し替え』。AI のレスポンス時間を UX 上 `隠す』 のが楽。

プログレッシブエンハンスメント × AI

` AI チャットで JS が読み込まれていない瞬間にも、フォームを押せばサーバが処理してくれる』。初回 LCP に効く。

関数呼び出しの集約

AI 関連の `要約』 `タグ生成』 `翻訳』 などを Server Actions として束ね、UI からは `関数を呼ぶ』 だけにすると、設計がシンプルになる。

AI 時代の Next.js アプリ』 と Server Actions』 は、設計思想として相性が良いペアになっています。

Server Actions に関するよくある質問

Q. Server Actions は本番運用に耐えますか?

A. Next.js 14.0 で stable』</strong>になっており、Vercel をはじめ多くの本番採用例があります。認証 / 認可 / 検証』 を関数の冒頭で必ず行うルールさえ守れば、安全に運用できます。

Q. API Routes はもう不要ですか?

A. 用途で残るケースは多い』</strong>です。<strong> 外部公開 API』 Webhook』 モバイルアプリから叩く』 用途は API Routes / Route Handlers の方が向きます。`内向きのアクションだけ Server Actions に寄せる』 のが現実的です。

Q. tRPC と Server Actions、どちらを使うべきですか?

A. 共存可能</strong></strong>です。複雑な型を持つ内部 API 群は tRPC、フォーム / 単純な CRUD は Server Actions』 と分けるチームも多いです。`どちらか一方を選ぶ』 必要はありません。

Q. ファイルアップロードを Server Actions で扱えますか?

A. 小〜中サイズなら可能、大サイズは別ルート』</strong>です。Next.js のリクエストサイズ制限(デフォルト 1MB / 4MB 程度)に注意し、大きいファイルは署名付き URL で S3 / R2 に直接アップロード』 する設計に分けます。

Q. エラー時のメッセージはどう表示しますか?

A. useActionState』 とreturn { error: '...' }』の組み合わせが標準パターンです。`throw して 500 になる』 と UX が悪いので、ユーザーに見せるエラーは値として返します。

Q. Server Actions は Vercel 以外でも動きますか?

A. はい。Next.js が動く環境ならどこでも(self-hosted Node、AWSCloudflare、Bun など)で動きます。`Vercel 以外で動かない』 という誤解を持ちやすい機能ですが、標準の Next.js 機能です。

Q. Server Actions を学ぶ最短ルートは?

A. ① 'use server'』 と

』 で1個のフォーム送信を書く、② useFormStatus』 で送信中ボタンを作る、③ revalidatePath』 でリスト再取得を試す、④ `useOptimistic』 で楽観的更新を入れる、の4段階で典型ユースケースを一通り体験できます。

参考リンク

あとで見返すならここで保存

読み終わったあとに残しておきたい記事は、お気に入りからまとめて辿れます。