diff --git a/orm/clerk-nextjs/.gitignore b/orm/clerk-nextjs/.gitignore
index ffa74efaabc7..bf8d09458d6e 100644
--- a/orm/clerk-nextjs/.gitignore
+++ b/orm/clerk-nextjs/.gitignore
@@ -21,10 +21,8 @@
/build
# misc
-**/generated/prisma
.DS_Store
*.pem
-prisma/dev.db*
# debug
npm-debug.log*
@@ -43,5 +41,4 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts
-# clerk configuration (can include secrets)
-/.clerk/
+/app/generated/prisma
diff --git a/orm/clerk-nextjs/README.md b/orm/clerk-nextjs/README.md
index e3ce2713f466..c891f26411ab 100644
--- a/orm/clerk-nextjs/README.md
+++ b/orm/clerk-nextjs/README.md
@@ -43,6 +43,7 @@ This example uses a [Prisma Postgres](https://prisma.io/postgres) database by de
1. Set up a new Prisma Postgres instance in the [Prisma Data Platform Console](https://console.prisma.io) and copy the database connection URL.
2. Add your database url to the `.env`
+3. Run `npx prisma migrate dev --name init`
That's it, your project is now configured to use Prisma Postgres!
diff --git a/orm/clerk-nextjs/src/app/api/posts/route.ts b/orm/clerk-nextjs/app/api/posts/route.ts
similarity index 100%
rename from orm/clerk-nextjs/src/app/api/posts/route.ts
rename to orm/clerk-nextjs/app/api/posts/route.ts
diff --git a/orm/clerk-nextjs/app/api/webhooks/clerk/route.ts b/orm/clerk-nextjs/app/api/webhooks/clerk/route.ts
new file mode 100644
index 000000000000..c26f1b144762
--- /dev/null
+++ b/orm/clerk-nextjs/app/api/webhooks/clerk/route.ts
@@ -0,0 +1,30 @@
+import { verifyWebhook } from '@clerk/nextjs/webhooks'
+import { NextRequest } from 'next/server'
+import prisma from '@/lib/prisma'
+
+export async function POST(req: NextRequest) {
+ try {
+ const evt = await verifyWebhook(req)
+ const { id } = evt.data
+ const eventType = evt.type
+ console.log(`Received webhook with ID ${id} and event type of ${eventType}`)
+
+ if (eventType === 'user.created') {
+ const { id, email_addresses, first_name, last_name } = evt.data
+ await prisma.user.upsert({
+ where: { clerkId: id },
+ update: {},
+ create: {
+ clerkId: id,
+ email: email_addresses[0].email_address,
+ name: `${first_name} ${last_name}`,
+ },
+ })
+ }
+
+ return new Response('Webhook received', { status: 200 })
+ } catch (err) {
+ console.error('Error verifying webhook:', err)
+ return new Response('Error verifying webhook', { status: 400 })
+ }
+}
diff --git a/orm/clerk-nextjs/src/app/components/PostInputs.tsx b/orm/clerk-nextjs/app/components/PostInputs.tsx
similarity index 65%
rename from orm/clerk-nextjs/src/app/components/PostInputs.tsx
rename to orm/clerk-nextjs/app/components/PostInputs.tsx
index f183d43944f8..6d0a6725cb62 100644
--- a/orm/clerk-nextjs/src/app/components/PostInputs.tsx
+++ b/orm/clerk-nextjs/app/components/PostInputs.tsx
@@ -1,24 +1,24 @@
-'use client'
+"use client";
-import { useState } from 'react'
+import { useState } from "react";
export default function PostInputs() {
- const [title, setTitle] = useState('')
- const [content, setContent] = useState('')
+ const [title, setTitle] = useState("");
+ const [content, setContent] = useState("");
async function createPost(e: React.FormEvent) {
- e.preventDefault()
- if (!title || !content) return
+ e.preventDefault();
+ if (!title || !content) return;
- await fetch('/api/posts', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
+ await fetch("/api/posts", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title, content }),
- })
+ });
- setTitle('')
- setContent('')
- location.reload()
+ setTitle("");
+ setContent("");
+ location.reload();
}
return (
@@ -40,5 +40,5 @@ export default function PostInputs() {
Post
- )
-}
+ );
+}
\ No newline at end of file
diff --git a/orm/clerk-nextjs/src/app/favicon.ico b/orm/clerk-nextjs/app/favicon.ico
similarity index 100%
rename from orm/clerk-nextjs/src/app/favicon.ico
rename to orm/clerk-nextjs/app/favicon.ico
diff --git a/orm/clerk-nextjs/src/app/globals.css b/orm/clerk-nextjs/app/globals.css
similarity index 100%
rename from orm/clerk-nextjs/src/app/globals.css
rename to orm/clerk-nextjs/app/globals.css
diff --git a/orm/clerk-nextjs/src/app/layout.tsx b/orm/clerk-nextjs/app/layout.tsx
similarity index 65%
rename from orm/clerk-nextjs/src/app/layout.tsx
rename to orm/clerk-nextjs/app/layout.tsx
index 9bd1894a539e..7e584607d4ed 100644
--- a/orm/clerk-nextjs/src/app/layout.tsx
+++ b/orm/clerk-nextjs/app/layout.tsx
@@ -1,6 +1,6 @@
-import type { Metadata } from 'next'
-import { Geist, Geist_Mono } from 'next/font/google'
-import './globals.css'
+import type { Metadata } from "next";
+import { Geist, Geist_Mono } from "next/font/google";
+import "./globals.css";
import {
ClerkProvider,
UserButton,
@@ -8,40 +8,39 @@ import {
SignUpButton,
SignedOut,
SignedIn,
-} from '@clerk/nextjs'
+} from "@clerk/nextjs";
const geistSans = Geist({
- variable: '--font-geist-sans',
- subsets: ['latin'],
-})
+ variable: "--font-geist-sans",
+ subsets: ["latin"],
+});
const geistMono = Geist_Mono({
- variable: '--font-geist-mono',
- subsets: ['latin'],
-})
+ variable: "--font-geist-mono",
+ subsets: ["latin"],
+});
export const metadata: Metadata = {
- title: 'Create Next App',
- description: 'Generated by create next app',
-}
+ title: "Create Next App",
+ description: "Generated by create next app",
+};
export default function RootLayout({
children,
}: Readonly<{
- children: React.ReactNode
+ children: React.ReactNode;
}>) {
return (
+ className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
{children}
- )
+ );
}
const Navbar = () => {
@@ -55,5 +54,5 @@ const Navbar = () => {
- )
-}
+ );
+};
\ No newline at end of file
diff --git a/orm/clerk-nextjs/src/app/page.tsx b/orm/clerk-nextjs/app/page.tsx
similarity index 63%
rename from orm/clerk-nextjs/src/app/page.tsx
rename to orm/clerk-nextjs/app/page.tsx
index 12198a103b84..1f0dc62c4271 100644
--- a/orm/clerk-nextjs/src/app/page.tsx
+++ b/orm/clerk-nextjs/app/page.tsx
@@ -1,15 +1,15 @@
-import { currentUser } from '@clerk/nextjs/server'
-import prisma from '@/lib/prisma'
-import PostInputs from './components/PostInputs'
+import { currentUser } from "@clerk/nextjs/server";
+import prisma from "@/lib/prisma";
+import PostInputs from "@/app/components/PostInputs";
export default async function Home() {
- const user = await currentUser()
- if (!user) return
Sign in to post
+ const user = await currentUser();
+ if (!user) return Sign in to post
;
const posts = await prisma.post.findMany({
where: { author: { clerkId: user.id } },
- orderBy: { createdAt: 'desc' },
- })
+ orderBy: { createdAt: "desc" },
+ });
return (
@@ -18,13 +18,12 @@ export default async function Home() {
{posts.map((post) => (
+ className="p-4 border border-zinc-800 rounded mt-4">
{post.title}
{post.content}
))}
- )
-}
+ );
+}
\ No newline at end of file
diff --git a/orm/clerk-nextjs/eslint.config.mjs b/orm/clerk-nextjs/eslint.config.mjs
deleted file mode 100644
index c85fb67c463f..000000000000
--- a/orm/clerk-nextjs/eslint.config.mjs
+++ /dev/null
@@ -1,16 +0,0 @@
-import { dirname } from "path";
-import { fileURLToPath } from "url";
-import { FlatCompat } from "@eslint/eslintrc";
-
-const __filename = fileURLToPath(import.meta.url);
-const __dirname = dirname(__filename);
-
-const compat = new FlatCompat({
- baseDirectory: __dirname,
-});
-
-const eslintConfig = [
- ...compat.extends("next/core-web-vitals", "next/typescript"),
-];
-
-export default eslintConfig;
diff --git a/orm/clerk-nextjs/lib/prisma.ts b/orm/clerk-nextjs/lib/prisma.ts
new file mode 100644
index 000000000000..726d1611985f
--- /dev/null
+++ b/orm/clerk-nextjs/lib/prisma.ts
@@ -0,0 +1,13 @@
+import { PrismaClient } from '../app/generated/prisma/client'
+import { withAccelerate } from '@prisma/extension-accelerate'
+
+const globalForPrisma = global as unknown as {
+ prisma: PrismaClient
+}
+
+const prisma =
+ globalForPrisma.prisma || new PrismaClient().$extends(withAccelerate())
+
+if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
+
+export default prisma
diff --git a/orm/clerk-nextjs/src/middleware.ts b/orm/clerk-nextjs/middleware.ts
similarity index 100%
rename from orm/clerk-nextjs/src/middleware.ts
rename to orm/clerk-nextjs/middleware.ts
diff --git a/orm/clerk-nextjs/package.json b/orm/clerk-nextjs/package.json
index 4786fdb2385f..235b2d6bbd89 100644
--- a/orm/clerk-nextjs/package.json
+++ b/orm/clerk-nextjs/package.json
@@ -1,5 +1,5 @@
{
- "name": "clerk-nextjs",
+ "name": "clerk2",
"version": "0.1.0",
"private": true,
"scripts": {
@@ -9,25 +9,20 @@
"lint": "next lint"
},
"dependencies": {
- "@clerk/nextjs": "6.28.1",
- "@prisma/client": "6.9.0",
- "@prisma/extension-accelerate": "2.0.2",
- "next": "15.3.5",
+ "@clerk/nextjs": "^6.30.1",
+ "@prisma/extension-accelerate": "^2.0.2",
+ "next": "15.4.6",
"react": "19.1.0",
- "react-dom": "19.1.0",
- "svix": "1.68.0"
+ "react-dom": "19.1.0"
},
"devDependencies": {
- "@eslint/eslintrc": "3.3.1",
- "@tailwindcss/postcss": "4.1.11",
- "@types/node": "22.15.32",
- "@types/react": "19.1.8",
- "@types/react-dom": "19.1.6",
- "eslint": "9.30.1",
- "eslint-config-next": "15.3.5",
- "prisma": "6.9.0",
- "tailwindcss": "4.1.11",
- "tsx": "4.20.3",
- "typescript": "5.8.3"
+ "@tailwindcss/postcss": "^4",
+ "@types/node": "^20",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "prisma": "^6.14.0",
+ "tailwindcss": "^4",
+ "tsx": "^4.20.4",
+ "typescript": "^5"
}
}
diff --git a/orm/clerk-nextjs/prisma/schema.prisma b/orm/clerk-nextjs/prisma/schema.prisma
index 0cb97b26e5b4..57b0a2d400b6 100644
--- a/orm/clerk-nextjs/prisma/schema.prisma
+++ b/orm/clerk-nextjs/prisma/schema.prisma
@@ -1,12 +1,6 @@
-// This is your Prisma schema file,
-// learn more about it in the docs: https://pris.ly/d/prisma-schema
-
-// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
-// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
-
generator client {
- provider = "prisma-client-js"
- output = "../src/app/generated/prisma"
+ provider = "prisma-client"
+ output = "../app/generated/prisma"
}
datasource db {
@@ -15,7 +9,7 @@ datasource db {
}
model User {
- id String @id @default(cuid())
+ id Int @id @default(autoincrement())
clerkId String @unique
email String @unique
name String?
@@ -23,11 +17,11 @@ model User {
}
model Post {
- id String @id @default(cuid())
+ id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
- authorId String
+ authorId Int
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now())
}
diff --git a/orm/clerk-nextjs/src/app/api/webhooks/clerk/route.ts b/orm/clerk-nextjs/src/app/api/webhooks/clerk/route.ts
deleted file mode 100644
index 0ee6769f89d8..000000000000
--- a/orm/clerk-nextjs/src/app/api/webhooks/clerk/route.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Webhook } from 'svix'
-import { WebhookEvent } from '@clerk/nextjs/server'
-import { headers } from 'next/headers'
-import prisma from '@/lib/prisma'
-
-export async function POST(req: Request) {
- const secret = process.env.SIGNING_SECRET
- if (!secret) return new Response('Missing secret', { status: 500 })
-
- const wh = new Webhook(secret)
- const body = await req.text()
- const headerPayload = await headers()
-
- const event = wh.verify(body, {
- 'svix-id': headerPayload.get('svix-id')!,
- 'svix-timestamp': headerPayload.get('svix-timestamp')!,
- 'svix-signature': headerPayload.get('svix-signature')!,
- }) as WebhookEvent
-
- if (event.type === 'user.created') {
- const { id, email_addresses, first_name, last_name } = event.data
- await prisma.user.upsert({
- where: { clerkId: id },
- update: {},
- create: {
- clerkId: id,
- email: email_addresses[0].email_address,
- name: `${first_name} ${last_name}`,
- },
- })
- }
-
- return new Response('OK')
-}
diff --git a/orm/clerk-nextjs/src/lib/prisma.ts b/orm/clerk-nextjs/src/lib/prisma.ts
deleted file mode 100644
index 15880f69129b..000000000000
--- a/orm/clerk-nextjs/src/lib/prisma.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { PrismaClient } from '../app/generated/prisma'
-import { withAccelerate } from '@prisma/extension-accelerate'
-
-const prisma = new PrismaClient().$extends(withAccelerate())
-
-const globalForPrisma = global as unknown as { prisma: typeof prisma }
-
-if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
-
-export default prisma
diff --git a/orm/clerk-nextjs/tsconfig.json b/orm/clerk-nextjs/tsconfig.json
index c1334095f876..d8b93235f205 100644
--- a/orm/clerk-nextjs/tsconfig.json
+++ b/orm/clerk-nextjs/tsconfig.json
@@ -19,7 +19,7 @@
}
],
"paths": {
- "@/*": ["./src/*"]
+ "@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],