Next.js(AppRouter)+Prisma+supabaseセットアップ
#いつもの
毎回無駄に探しているのでまとめる
ここでは Prisma とは Prisma ORMを指す
SEO: Next.js supabase Prisma Vercel
アプリ作る
bunx create-next-app@latest
supabaseセットアップ
プロジェクト作成 このときセットするパスワードはDBのパスワードにもなるのでメモっておく
https://supabase.com/
Prismaセットアップ
bun a -D prisma
https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project/relational-databases-typescript-postgresql
PrismaとSupabaseの接続
直接PostgreSQLに接続するわけではないので微妙に気を使う必要がある。
https://supabase.com/partners/integrations/prisma
具体的には
アプリで使うときは Transaction mode
schema migration などは Session mode
code:shell
mkdir prisma
touch prisma/schema.prisma
code:.env
DATABASE_URL=...
DIRECT_URL=...
Database URL(transaction mode)はこんな形式
postgres://[db-user].[project-ref]:[db-password]@aws-0-[aws-region].pooler.supabase.com:6543/[db-name]?pgbouncer=true&connection_limit=1
Direct URL(Session mode)はこんな形式
postgres://[db-user].[project-ref]:[db-password]@aws-0-[aws-region].pooler.supabase.com:5432/[db-name]
各種URLは https://supabase.com/dashboard/project/[projectId]/settings/database から取得可能
GUIだと
プロジェクトページ
-> Project Settings(左下)
-> Configuration/Database
-> Database Settings/Connection string
^ なくなった
https://scrapbox.io/files/67594a73cf4b4b275d928110.png
https://scrapbox.io/files/67594c7d3b20d4e40e5bc230.png
コピペしてくるとURLにクエリパラメーターついてないからつける
code:schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
}
初期化
code:shell
bunx prisma migrate dev --name init
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "aws-0-ap-northeast-1.pooler.supabase.com:6543"
Next.jsからPrismaでSupabaseにつなぐ
https://www.prisma.io/docs/orm/more/help-and-troubleshooting/help-articles/nextjs-prisma-client-dev-practices
mkdir src/lib して
code:typescript
// https://www.prisma.io/docs/orm/more/help-and-troubleshooting/help-articles/nextjs-prisma-client-dev-practices
import { PrismaClient } from "@prisma/client";
const prismaClientSingleton = () => {
return new PrismaClient();
};
declare const globalThis: {
prismaGlobal: ReturnType<typeof prismaClientSingleton>;
} & typeof global;
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();
export { prisma };
if (process.env.NODE_ENV !== "production") globalThis.prismaGlobal = prisma;
初期データの投入
https://www.prisma.io/docs/orm/prisma-migrate/workflows/seeding
code:script/seed.ts
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const alice = await prisma.user.upsert({
where: { email: 'alice@prisma.io' },
update: {},
create: {
email: 'alice@prisma.io',
name: 'Alice',
posts: {
create: {
title: 'Check out Prisma with Next.js',
content: 'https://www.prisma.io/nextjs',
published: true,
},
},
},
})
const bob = await prisma.user.upsert({
where: { email: 'bob@prisma.io' },
update: {},
create: {
email: 'bob@prisma.io',
name: 'Bob',
posts: {
create: [
{
title: 'Follow Prisma on Twitter',
content: 'https://twitter.com/prisma',
published: true,
},
{
title: 'Follow Nexus on Twitter',
content: 'https://twitter.com/nexusgql',
published: true,
},
],
},
},
})
console.log({ alice, bob })
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
Opt: Vercelで使う場合
https://scrapbox.io/files/673d91f9c62e0da70f968d47.png
https://www.prisma.io/docs/orm/more/help-and-troubleshooting/help-articles/vercel-caching-issue
2025/6/4
Use Supabase with Next.js | Supabase Docs