⚡
【Next.js + Supabase】`cookies` was called outside a request scope.の解決方法
エラー状況
npm run build
でビルド時に下記のエラーが発生しました。
しかも、開発環境では発生せずに正常に動作していました。
Collecting page data ..Error: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context
結論
エラー発生時はsupabaseクライアントを関数外で作成していました。
// 関数外でクライアント作成
const supabase = createClient()
export const fetchStudent = async () => {
const { data } = await supabase.from('student').select()
return data
}
export const fetchTeacher = async () => {
const { data } = await supabase.from('teacher').select()
return data
}
supabaseクライアントを関数内で作成することで解決できました。
export const fetchStudent = async () => {
// 関数内に移動
const supabase = createClient()
const { data } = await supabase.from('student').select()
return data
}
export const fetchTeacher = async () => {
// 関数内に移動
const supabase = createClient()
const { data } = await supabase.from('teacher').select()
return data
}
なぜエラーが発生したか?
エラーメッセージで案内された公式ドキュメントによると、動的APIをリクエスト外で呼び出すと発生するようです。
Cookieのようにリクエスト時にのみ分かる情報は動的APIに該当します。
@supabase/ssrのサーバー側のクライアント作成ではCookieを使用しているので、今回のエラーが発生していました。
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'
export function createClient() {
const cookieStore = cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
}
},
},
}
)
}
そもそも...
Supabaseの公式ドキュメントにサーバー側では毎回クライアントを作成するように説明がありました。
クライアント側ではシングルトンパターンになっていて、何回呼び出しても1つしか作成されないようです。
参考サイト
Discussion