🍪
【Next.js 15】Server Actions で cookie を利用する
当時 Next.js の最新バージョンだった v12 で作ったサイトが時代の変化に取り残され化石と化していたので、今さらながらアップデートを行いました。
大きなトピックは Pages Router から App Router への移行でしたが、他の機能として個人的に嬉しかった cookie の標準サポートについて、躓いたポイントをメモとして残します。
1. [サーバーコンポーネント] cookie を設定する関数を用意する
まずは cookie を設定する関数を用意します。これは Server Actions のため、サーバーコンポーネントで準備する必要があります。
src/liblaries/cookie.ts
'use server';
import { cookies } from 'next/headers';
export const setCookie: (name: string, value: string) => Promise<void> = async (
name: string,
value: string
) => {
const cookieStore = await cookies();
cookieStore.set({ name, value });
};
クライアントコンポーネントで呼び出した場合、以下のようなエラーが発生します。
next/headers
からの cookies
の import は、サーバーコンポーネントしか行えないようですね。
2. [クライアントコンポーネント] 用意した関数を呼び出し、cookie を設定する
- で用意した
setCookie()
は、クライアントコンポーネントで呼び出す必要があります。
src/app/components/Container.tsx
'use client';
import { setCookie } from '@/libraries/cookie';
export const Container = () => {
...
await setCookie('name', 'value');
...
Server Action そのものはサーバーコンポーネントでもクライアントコンポーネントでも呼び出すことが可能ですが、await cookies().set
に関してはこの限りではないようです。
サーバーコンポーネントで呼び出した場合、以下のようなエラーが発生します。
3. [サーバーコンポーネント] 設定した cookie を読み込む
例えば、cookie に登録してある情報を meta タグ内で用いる、といったこともここでは簡単にできます。
'use server';
import { Metadata } from 'next';
import { cookies } from 'next/headers';
import { Container } from '@/components/Container';
export async function generateMetadata(): Promise<Metadata> {
const cookieStore = await cookies();
const title = cookieStore.get('title')?.value;
const description = cookieStore.get('description')?.value;
return { title, description };
}
export const HomePage = () => (
<Container>
...
クライアントコンポーネントで呼び出した場合、1と同じエラーが発生します。
おわりに
慣れるとなんてことない利用法なのかもしれませんが、使わないうちに忘れてしまいそうなので、発生するエラーを含めてまとめてみました。
どなたかのお力になれれば幸いです。
Discussion