概要
next/headers の cookies() を使うと、サーバーサイドでクッキーを読み書きできる。
クライアントコンポーネントから直接参照できないため、セッショントークンなどを安全に扱える。
インストール
# 追加インストールは不要
Server Component でクッキーを読む
// src/app/dashboard/page.tsx
import { cookies } from "next/headers";
export default async function DashboardPage() {
const cookieStore = await cookies();
const theme = cookieStore.get("theme")?.value ?? "light";
return (
<main className="p-6">
<p className="text-sm">現在のテーマ: {theme}</p>
</main>
);
}
Server Actions でクッキーを書く
// src/app/actions/theme.ts
"use server";
import { cookies } from "next/headers";
export async function setTheme(theme: "light" | "dark") {
const cookieStore = await cookies();
cookieStore.set("theme", theme, {
httpOnly: false,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
maxAge: 60 * 60 * 24 * 365, // 1年
path: "/",
});
}
// src/components/ThemeToggle.tsx
"use client";
import { setTheme } from "@/app/actions/theme";
export function ThemeToggle() {
return (
<div className="flex gap-2">
<button onClick={() => setTheme("light")} className="rounded border px-3 py-1 text-sm">
ライト
</button>
<button onClick={() => setTheme("dark")} className="rounded border px-3 py-1 text-sm">
ダーク
</button>
</div>
);
}
Route Handler でセッショントークンを管理する
// src/app/api/session/route.ts
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const { token } = (await request.json()) as { token: string };
const cookieStore = await cookies();
cookieStore.set("session", token, {
httpOnly: true, // JS から読めない(XSS 対策)
secure: process.env.NODE_ENV === "production",
sameSite: "strict",
maxAge: 60 * 60 * 24 * 7, // 7日
path: "/",
});
return NextResponse.json({ ok: true });
}
export async function DELETE() {
const cookieStore = await cookies();
cookieStore.delete("session");
return NextResponse.json({ ok: true });
}
ポイント
cookies()は Server Component / Server Actions / Route Handler でのみ使用可能httpOnly: trueにすると JavaScript からアクセスできず、XSS によるトークン盗用を防ぐsecure: trueは HTTPS 接続時のみクッキーを送信する(本番環境で必須)sameSite: "strict"は CSRF 対策になるが、外部サイトからの遷移でクッキーが送られない点に注意- Next.js 15 では
cookies()は非同期関数(awaitが必要)