Next.js (App Router) と Supabase の“最短連携フロー”を、サクッとまとめました。
公式で推奨されている手順をわかりやすくまとめています。
@supabase/supabase-js と @supabase/ssr の役割の違いの記載しております。
📌 参考サイト
📌 使用ツール
- Next.js (App Router) / TypeScript
- Supabase (Auth & DB)
- Vercel(任意)
📌 導入手順
①パッケージ導入
# npm
npm i @supabase/supabase-js @supabase/ssr
# or yarn
yarn add @supabase/supabase-js @supabase/ssr
# or pnpm
pnpm add @supabase/supabase-js @supabase/ssr
@supabase/supabase-js
- Supabaseの提供している基本機能ライブラリ。
ブラウザ・Node.js・Edgeなど全環境で使える汎用クライアント。 - createClientを使って自由に構築できるが、SSR環境でのCookieやセッション管理は 別途実装が必要!(
@supabase/ssrと並行使用)
@supabase/ssr
- Next.jsのようにサーバーサイドレンダリング(SSR)を使う環境に特化した便利ツール集。
- createBrowserClient / createServerClient などの関数で、Cookieやトークン管理を自動化。
- App Router構成ではこちらを使うと、認証状態の維持が簡単になる。
② 環境変数設定
# .env.local に追記
NEXT_PUBLIC_SUPABASE_URL=あなたのSupabaseプロジェクトURL
NEXT_PUBLIC_SUPABASE_ANON_KEY=あなたのAnon(公開)キー
プロジェクトルート/
├── .env.local // ← ここにSupabaseのURLとAnonキーを記載
├── package.json
├── tsconfig.json
├── next.config.js
└── src/
└── utils/
└── supabase/
├── clients.ts // ブラウザ用クライアント(createBrowserClientなど)
└── server.ts // サーバー用クライアント(createServerClientなど)
③ Database 型を自動生成
上記公式サイトを参考に、ご自身のテーブル作成後
TypeScriptの自動生成を行います。
導入することで <Datebase> と記載するだけで簡単に型定義ができます。
# Supabase CLI が未導入の場合
npm install supabase --save-dev
# 型定義ファイルを生成
npx supabase gen types typescript --project-id <PROJECT_ID> > src/types/database.types.ts
プロジェクトルート/
├─ src/
│ ├─ types/
│ │ └─ database.types.ts # 自動生成されたDBスキーマ型
│ └─ utils/
│ └─ supabase/
│ ├─ clients.ts # ブラウザ用クライアント
│ └─ server.ts # サーバ用クライアント
├─ supabase/ # CLIで作られるDBマイグレーション等
├─ package.json
└─ .env.local
④ クライアント作成ファイルの配置(App Router向け:ブラウザ/サーバを分離)
配置場所を用意
mkdir -p src/utils/supabase
touch src/utils/supabase/clients.ts src/utils/supabase/server.ts
# 下記のような配置がおすすめ
src/
└── utils/
└── supabase/
├── clients.ts // ブラウザ用(createBrowserClientなど)
└── server.ts // サーバー用(createServerClientなど)
クライアント側コード作成
Supabase公式のクライアント作成例に、TypeScript型を適用しています。
"use client";
// 📍ブラウザで使用する Supabase クライアントを生成
// NEXT_PUBLIC_環境変数を使い、React クライアントで Supabase を利用可能にする
import { createBrowserClient } from "@supabase/ssr";
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@/types/database.types";
export function createClient(): SupabaseClient<Database> {
return createBrowserClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
);
}
補足:SupabaseClient<Database> の意味
-
SupabaseClientは@supabase/supabase-jsが提供するクライアント型。 -
③で作成した型定義を導入。
<Database>の部分に、自分のSupabaseプロジェクトのDBスキーマ型database.types.tsを渡すことで、クエリ時に型安全が効く。例:存在しないテーブル名やカラム名を指定すると、コンパイル時にエラーになる。
サーバー側コード作成
Supabase公式のサーバー作成例に、TypeScript型を適用しています。
// 📍Server Component や API Route で使用
// Next.js の cookies() を使ってセッション管理された Supabase クライアントを生成
import { createServerClient } from "@supabase/ssr";
import type { SupabaseClient } from "@supabase/supabase-js";
import { cookies } from "next/headers";
import type { Database } from "../../../supabase/database.types";
export async function createClient(): Promise<SupabaseClient<Database>> {
const cookieStore = await cookies();
return createServerClient<Database>(
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 {
// `setAll` メソッドは Server Component から呼び出されました。
// ミドルウェアでユーザーセッションを更新している場合は、この警告は無視してかまいません。
}
},
},
},
);
}
補足:Promise<SupabaseClient<Database>> の意味
1)Promise<...>
- 関数が async のため、戻り値は 非同期で解決されるPromise 型になります。
- 呼び出し時は await が必要です。
2)SupabaseClient<Database>
- 上記にて記載。
📌 まとめ
-
@supabase/supabase-jsはSupabaseのコアSDK、@supabase/ssrはSSR環境向けのヘルパー。 - App Router構成では、ブラウザ側は
createBrowserClient<Database>、サーバ側はcreateServerClient<Database>を使い分けるのが公式推奨。 -
Database型をSupabase CLIで自動生成し、SupabaseClient<Database>として適用することで、クエリ時に型安全&補完が効く。 - サーバ側関数は
Promise<SupabaseClient<Database>>となり、呼び出し時はawaitが必要。 - ディレクトリ構成を整理し、
src/utils/supabase/とsrc/types/に分けて管理すると保守性が高まる。