feat: add clerk integration to next-template
This commit is contained in:
parent
14ef2719c7
commit
a5faf21953
6 changed files with 112 additions and 3 deletions
3
apps/next-template/.gitignore
vendored
Normal file
3
apps/next-template/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
# clerk configuration (can include secrets)
|
||||||
|
/.clerk/
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
"clean": "rm -rf .next"
|
"clean": "rm -rf .next"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@clerk/nextjs": "^6.22.0",
|
||||||
"@repo/logger": "*",
|
"@repo/logger": "*",
|
||||||
"@repo/ui": "*",
|
"@repo/ui": "*",
|
||||||
"next": "^15.3.0",
|
"next": "^15.3.0",
|
||||||
|
|
|
||||||
23
apps/next-template/src/app/clerk/page.tsx
Normal file
23
apps/next-template/src/app/clerk/page.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
CardContent,
|
||||||
|
} from "@repo/ui/components/card";
|
||||||
|
|
||||||
|
export default function ClerkTestPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center min-h-screen bg-muted">
|
||||||
|
<Card className="w-full max-w-md shadow-lg">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Welcome, you are logged in!</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
This is a protected test page.
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
import "@repo/ui/styles/styles.css";
|
import "@repo/ui/styles/styles.css";
|
||||||
import "@repo/ui/styles/global.css";
|
import "@repo/ui/styles/global.css";
|
||||||
|
import {
|
||||||
|
ClerkProvider,
|
||||||
|
SignInButton,
|
||||||
|
SignUpButton,
|
||||||
|
SignedIn,
|
||||||
|
SignedOut,
|
||||||
|
UserButton,
|
||||||
|
} from "@clerk/nextjs";
|
||||||
|
import { Button } from "@repo/ui/components/button";
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
|
|
@ -7,8 +16,24 @@ export default function RootLayout({
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<ClerkProvider>
|
||||||
<body>{children}</body>
|
<html lang="en">
|
||||||
</html>
|
<body>
|
||||||
|
<header className="flex items-center justify-end py-4 px-6 bg-white shadow-sm mb-6">
|
||||||
|
<div>
|
||||||
|
<SignedOut>
|
||||||
|
<SignInButton mode="modal">
|
||||||
|
<Button variant="outline">Sign In</Button>
|
||||||
|
</SignInButton>
|
||||||
|
</SignedOut>
|
||||||
|
<SignedIn>
|
||||||
|
<UserButton afterSignOutUrl="/" />
|
||||||
|
</SignedIn>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{children}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</ClerkProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
apps/next-template/src/middleware.ts
Normal file
28
apps/next-template/src/middleware.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
|
||||||
|
|
||||||
|
const isProtectedRoute = createRouteMatcher(["/clerk(.*)"]);
|
||||||
|
|
||||||
|
export default clerkMiddleware(async (auth, req) => {
|
||||||
|
// Uncomment the following line to enable Clerk's default behavior | Redirect to sign-in page if the user is not authenticated
|
||||||
|
// if (isProtectedRoute(req)) await auth.protect();
|
||||||
|
|
||||||
|
// More control over authentication flow
|
||||||
|
const { userId, redirectToSignIn } = await auth();
|
||||||
|
|
||||||
|
if (!userId && isProtectedRoute(req)) {
|
||||||
|
// Add custom logic to run before redirecting
|
||||||
|
console.log(
|
||||||
|
"User is not authenticated, redirecting to sign-in page..."
|
||||||
|
);
|
||||||
|
return redirectToSignIn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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)(.*)",
|
||||||
|
],
|
||||||
|
};
|
||||||
29
package-lock.json
generated
29
package-lock.json
generated
|
|
@ -125,6 +125,7 @@
|
||||||
"apps/next-template": {
|
"apps/next-template": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@clerk/nextjs": "^6.22.0",
|
||||||
"@repo/logger": "*",
|
"@repo/logger": "*",
|
||||||
"@repo/ui": "*",
|
"@repo/ui": "*",
|
||||||
"next": "^15.3.0",
|
"next": "^15.3.0",
|
||||||
|
|
@ -1080,6 +1081,28 @@
|
||||||
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0"
|
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@clerk/nextjs": {
|
||||||
|
"version": "6.22.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@clerk/nextjs/-/nextjs-6.22.0.tgz",
|
||||||
|
"integrity": "sha512-Lh+hq4iuvuSgiWSDHDM9BAM8+YZU/wtADGo2TAU7FBVEZ6I3SwyXo5JEY4F7s30TpH3kS9qC/Ye3YA6VIOOu7Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@clerk/backend": "^2.1.0",
|
||||||
|
"@clerk/clerk-react": "^5.32.0",
|
||||||
|
"@clerk/shared": "^3.9.7",
|
||||||
|
"@clerk/types": "^4.60.1",
|
||||||
|
"server-only": "0.0.1",
|
||||||
|
"tslib": "2.8.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.17.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"next": "^13.5.7 || ^14.2.25 || ^15.2.3",
|
||||||
|
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-0",
|
||||||
|
"react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@clerk/remix": {
|
"node_modules/@clerk/remix": {
|
||||||
"version": "4.8.1",
|
"version": "4.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@clerk/remix/-/remix-4.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@clerk/remix/-/remix-4.8.1.tgz",
|
||||||
|
|
@ -15457,6 +15480,12 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/server-only": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/set-cookie-parser": {
|
"node_modules/set-cookie-parser": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue