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

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 と何が違うの?

に関数を渡せるって本当?」 ── Next.js 14 / 15 で安定化した Server Actions は、「フォームと API のあり方」 を大きく変える React の新機能です。

ざっくり言うと、Server Actions は 「 サーバで動く関数を、クライアント側のコードから関数として呼べる」 仕組み です。 従来 「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 という棲み分けです。 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 を書かなくていい」 と聞くと万能に思えるかもしれませんが、` 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になっており、Vercel をはじめ多くの本番採用例があります。「認証 / 認可 / 検証」 を関数の冒頭で必ず行うルールさえ守れば、安全に運用できます。

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

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

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

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

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

A. 小〜中サイズなら可能、大サイズは別ルートです。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段階で典型ユースケースを一通り体験できます。

参考リンク

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

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