diff --git a/docs/integrations/databases/prisma-postgres.mdx b/docs/integrations/databases/prisma-postgres.mdx new file mode 100644 index 0000000000..a107b211e3 --- /dev/null +++ b/docs/integrations/databases/prisma-postgres.mdx @@ -0,0 +1,220 @@ +--- +title: Integrate Prisma Postgres with Clerk +description: Learn how to integrate Clerk into your Prisma Postgres application. +--- + + + +Now that you've set up Clerk authentication in your Next.js application, let's add Prisma Postgres to store and manage user data. In this guide, you'll create a simple messaging app where users can store and manage their personal messages. + + + ## Integrate the Next.js Clerk SDK + + Follow the [Next.js quickstart](/docs/quickstarts/nextjs) to integrate the Clerk Next.js SDK into your application. + + ## Install Prisma + + Install Prisma and the Prisma Client: + + ```sh {{ filename: 'terminal' }} + npm install prisma tsx --save-dev + npm install @prisma/extension-accelerate + ``` + + ## Protect your application routes + + To ensure that only authenticated users can access your application, modify [`clerkMiddleware`](/docs/references/nextjs/clerk-middleware) to require authentication for every route. + + ```typescript {{ filename: 'middleware.ts', mark: [[3, 5]] }} + import { clerkMiddleware } from '@clerk/nextjs/server' + + export default clerkMiddleware(async (auth) => { + await auth.protect() + }) + + export const config = { + matcher: [ + // Skip Next.js internals and all static files, unless found in search params + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + // Always run for API routes + '/(api|trpc)(.*)', + ], + } + ``` + + ## Set up the application schema and database connection + + Next, you'll need to initialize Prisma and set up a Prisma Postgres database. + + Run the following command to start a local Prisma Postgres database: + + ```sh {{ filename: 'terminal' }} + npx prisma dev + ``` + + Initialize Prisma in your project: + + ```sh {{ filename: 'terminal' }} + npx prisma init --output ../app/generated/prisma + ``` + + After initializing Prisma, your environment variable file should have the following values: + + ```env {{ filename: '.env' }} + DATABASE_URL=PRISMA_POSTGRES_CONNECTION_STRING + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} + CLERK_SECRET_KEY={{secret}} + ``` + + You will find the file `schema.prisma` in the `prisma/` directory, this defines the database schema. Add to the schema a new table called `UserMessage` with the columns `user_id`, `create_ts`, and `message`. The `user_id` column will be used to store the user's Clerk ID. You will need to change the provider from "prisma-client-js" to "prisma-client". + + ```prisma {{ filename: 'prisma/schema.prisma', ins: [2], del: [3] }} + generator client { + provider = "prisma-client" + provider = "prisma-client-js" + output = "../app/generated/prisma" + } + + datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + } + + model UserMessage { + user_id String @id + create_ts DateTime @default(now()) + message String + } + ``` + + ## Push the schema to the database + + Run the following command to push the schema to the database: + + ```sh {{ filename: 'terminal' }} + npx prisma db push + ``` + + ## Create a reusable Prisma Client instance + + To be able to use the Prisma Client instance globally in your code, create a reusable Prisma Client instance in `lib/prisma.ts`: + + ```typescript {{ filename: 'lib/prisma.ts' }} + import { PrismaClient } from '../app/generated/prisma/client' + + const globalForPrisma = globalThis as unknown as { + prisma: PrismaClient | undefined + } + + export const prisma = globalForPrisma.prisma ?? new PrismaClient() + + if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma + + export default prisma + ``` + + ## Create Server Actions to handle user interactions + + To handle form submissions for adding and deleting user messages, create two Server Actions in `app/actions.ts`. Use Clerk's [`auth()` helper](/docs/references/nextjs/auth) to obtain the user ID, which will be used to interact with the database. + + ```typescript {{ filename: 'app/actions.ts' }} + 'use server' + + import { auth } from '@clerk/nextjs/server' + import prisma from '@/lib/prisma' + import { revalidatePath } from 'next/cache' + + export async function createUserMessage(formData: FormData) { + const { userId } = await auth() + if (!userId) throw new Error('User not found') + const message = formData.get('message') as string + await prisma.userMessage.create({ + data: { + user_id: userId, + message, + }, + }) + + revalidatePath('/') + } + export async function deleteUserMessage() { + const { userId } = await auth() + if (!userId) throw new Error('User not found') + await prisma.userMessage.deleteMany({ + where: { user_id: userId }, + }) + + revalidatePath('/') + } + ``` + + ## Create the UI for the Home Page + + In your `app/page.tsx` file, add the following code to create the UI for the home page. If a message exists, the user can view and delete it; otherwise, they can add a new message. + + To retrieve the user's messages, use Clerk's [`auth()` helper](/docs/references/nextjs/auth) to obtain the user's ID. Then, use this ID to query the database for the user's messages. + + To enable the user to delete or add a message, use the `deleteUserMessage()` and `createUserMessage()` actions created in the previous step. + + ```tsx {{ filename: 'app/page.tsx' }} + import { createUserMessage, deleteUserMessage } from './actions' + import prisma from '@/lib/prisma' + import { auth } from '@clerk/nextjs/server' + + export default async function Home() { + const { userId } = await auth() + if (!userId) throw new Error('User not found') + const existingMessage = await prisma.userMessage.findUnique({ + where: { user_id: userId }, + }) + + return ( +
+
+

Prisma + Clerk Example

+ {existingMessage ? ( +
+

{existingMessage.message}

+
+ +
+
+ ) : ( +
+ + +
+ )} +
+
+ ) + } + ``` + + ## Run the application + + Run your application and open `http://localhost:3000` in your browser. Sign in with Clerk and interact with the application to add and delete user messages. +
diff --git a/docs/integrations/overview.mdx b/docs/integrations/overview.mdx index 4125ba5ade..def2b5aeef 100644 --- a/docs/integrations/overview.mdx +++ b/docs/integrations/overview.mdx @@ -72,6 +72,12 @@ description: Learn about the available integrations with Clerk. --- + - [Prisma Postgres](/docs/integrations/databases/prisma-postgres) + - Build applications using Prisma Postgres with Clerk as your authentication provider. + - {} + + --- + - [Shopify](/docs/integrations/shopify) - Use Clerk as your preferred Auth solution for your Shopify store. - {} diff --git a/docs/manifest.json b/docs/manifest.json index 50f70db314..cb5e6543ec 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -3838,6 +3838,10 @@ { "title": "Neon", "href": "/docs/integrations/databases/neon" + }, + { + "title": "Prisma Postgres", + "href": "/docs/integrations/databases/prisma-postgres" } ] ]