2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.js (App Router) と Supabase の最短連携方法

2
Last updated at Posted at 2025-08-10

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/ に分けて管理すると保守性が高まる。
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?