Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions app/(auth)/sign-in/[[...sign-in]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'

export default function SignInPage() {
return (
<div className="min-h-screen grid w-full items-center bg-zinc-100 px-4 font-mono text-sm">
<SignIn.Root>
<SignIn.Step
name="start"
className="mx-auto w-full sm:w-96 space-y-6 bg-white px-4 py-8 border-4 border-black shadow-[8px_8px_0_0_#000]"
>
<header className="text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 40 40"
className="mx-auto h-12 w-12 text-black"
aria-hidden
>
<rect width="40" height="40" fill="#000" />
<rect x="8" y="8" width="24" height="24" fill="#fff" />
</svg>
<h1 className="mt-3 text-base font-bold tracking-wide text-black uppercase">
Sign in to Clover
</h1>
</header>

<Clerk.GlobalError className="block text-sm text-red-500" />

{/* GOOGLE LOGIN */}
<Clerk.Connection
name="google"
className="flex w-full items-center justify-center gap-3 px-4 py-2 bg-yellow-400 border-2 border-black shadow-[4px_4px_0_0_#000] active:translate-y-[2px] active:shadow-none font-bold"
>
<span className="text-black">Login with Google</span>
</Clerk.Connection>

{/* EMAIL & PASSWORD */}
<div className="space-y-4">
<Clerk.Field name="identifier" className="space-y-1">
<Clerk.Label className="font-bold text-black uppercase">Email</Clerk.Label>
<Clerk.Input
type="email"
required
className="w-full px-3 py-2 bg-white border-2 border-black shadow-[3px_3px_0_0_#000] outline-none focus:border-yellow-500"
/>
<Clerk.FieldError className="text-sm text-red-500" />
</Clerk.Field>

<Clerk.Field name="password" className="space-y-1">
<Clerk.Label className="font-bold text-black uppercase">Password</Clerk.Label>
<Clerk.Input
type="password"
required
className="w-full px-3 py-2 bg-white border-2 border-black shadow-[3px_3px_0_0_#000] outline-none focus:border-yellow-500"
/>
<Clerk.FieldError className="text-sm text-red-500" />
</Clerk.Field>
</div>

{/* SUBMIT BUTTON */}
<SignIn.Action
submit
className="w-full px-4 py-2 bg-yellow-400 border-2 border-black shadow-[4px_4px_0_0_#000] active:translate-y-[2px] active:shadow-none text-black font-bold uppercase"
>
Sign In
</SignIn.Action>

<p className="text-center text-xs text-black">
No account?{' '}
<Clerk.Link
navigate="sign-up"
className="font-bold underline underline-offset-2 hover:text-yellow-600"
>
Create an account
</Clerk.Link>
</p>
</SignIn.Step>
</SignIn.Root>
</div>
)
}

118 changes: 118 additions & 0 deletions app/(auth)/sign-up/[[...sign-up]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@

'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignUp from '@clerk/elements/sign-up'

export default function SignUpPage() {
return (
<div className="min-h-screen grid w-full items-center bg-zinc-900 px-4 font-mono text-sm text-white">
<SignUp.Root>
<SignUp.Step
name="start"
className="mx-auto w-full sm:w-96 space-y-6 bg-zinc-800 px-4 py-8 border-4 border-black shadow-[8px_8px_0_0_#000]"
>
<header className="text-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 40 40" className="mx-auto h-12 w-12 text-yellow-400" aria-hidden>
<rect width="40" height="40" fill="#000" />
<rect x="8" y="8" width="24" height="24" fill="#FFD700" />
</svg>
<h1 className="mt-3 text-base font-bold tracking-wide text-yellow-400 uppercase">Create Account</h1>
</header>

<Clerk.GlobalError className="block text-sm text-red-500" />

<div className="space-y-4">
<Clerk.Field name="emailAddress" className="space-y-1">
<Clerk.Label className="font-bold text-yellow-400 uppercase">Email</Clerk.Label>
<Clerk.Input
type="email"
required
className="w-full px-3 py-2 bg-zinc-900 border-2 border-black shadow-[3px_3px_0_0_#000] outline-none focus:border-yellow-400 text-white"
/>
<Clerk.FieldError className="text-sm text-red-500" />
</Clerk.Field>

<Clerk.Field name="password" className="space-y-1">
<Clerk.Label className="font-bold text-yellow-400 uppercase">Password</Clerk.Label>
<Clerk.Input
type="password"
required
className="w-full px-3 py-2 bg-zinc-900 border-2 border-black shadow-[3px_3px_0_0_#000] outline-none focus:border-yellow-400 text-white"
/>
<Clerk.FieldError className="text-sm text-red-500" />
</Clerk.Field>
</div>

<SignUp.Action submit className="w-full px-4 py-2 bg-yellow-400 border-2 border-black shadow-[4px_4px_0_0_#000] active:translate-y-[2px] active:shadow-none text-black font-bold uppercase">
Sign Up
</SignUp.Action>

<p className="text-center text-xs text-yellow-400">
Already have an account?{' '}
<Clerk.Link navigate="sign-in" className="font-bold underline underline-offset-2 hover:text-yellow-200">
Sign in
</Clerk.Link>
</p>
</SignUp.Step>

{/* Verification Step */}
<SignUp.Step
name="verifications"
className="mx-auto w-full sm:w-96 space-y-6 bg-zinc-800 px-4 py-8 border-4 border-black shadow-[8px_8px_0_0_#000]"
>
<header className="text-center">
<h1 className="mt-3 text-base font-bold tracking-wide text-yellow-400 uppercase">Verify Email Code</h1>
</header>

<Clerk.GlobalError className="block text-sm text-red-500" />
<SignUp.Strategy name="email_code">
<Clerk.Field name="code" className="space-y-1">
<Clerk.Label className="font-bold text-yellow-400 uppercase">Email Code</Clerk.Label>
<Clerk.Input type="otp" required className="w-full px-3 py-2 bg-zinc-900 border-2 border-black shadow-[3px_3px_0_0_#000] outline-none focus:border-yellow-400 text-white" />
<Clerk.FieldError className="text-sm text-red-500" />
</Clerk.Field>
<SignUp.Action submit className="w-full px-4 py-2 bg-yellow-400 border-2 border-black shadow-[4px_4px_0_0_#000] active:translate-y-[2px] active:shadow-none text-black font-bold uppercase">
Verify
</SignUp.Action>
</SignUp.Strategy>

<p className="text-center text-xs text-yellow-400">
Already have an account?{' '}
<Clerk.Link navigate="sign-in" className="font-bold underline underline-offset-2 hover:text-yellow-200">
Sign in
</Clerk.Link>
</p>
</SignUp.Step>

{/* Continue Registration Step */}
<SignUp.Step
name="continue"
className="mx-auto w-full sm:w-96 space-y-6 bg-zinc-800 px-4 py-8 border-4 border-black shadow-[8px_8px_0_0_#000]"
>
<header className="text-center">
<h1 className="mt-3 text-base font-bold tracking-wide text-yellow-400 uppercase">Continue Registration</h1>
</header>

<Clerk.GlobalError className="block text-sm text-red-500" />
<Clerk.Field name="username" className="space-y-1">
<Clerk.Label className="font-bold text-yellow-400 uppercase">Username</Clerk.Label>
<Clerk.Input type="text" required className="w-full px-3 py-2 bg-zinc-900 border-2 border-black shadow-[3px_3px_0_0_#000] outline-none focus:border-yellow-400 text-white" />
<Clerk.FieldError className="text-sm text-red-500" />
</Clerk.Field>
<SignUp.Action submit className="w-full px-4 py-2 bg-yellow-400 border-2 border-black shadow-[4px_4px_0_0_#000] active:translate-y-[2px] active:shadow-none text-black font-bold uppercase">
Continue
</SignUp.Action>

<p className="text-center text-xs text-yellow-400">
Already have an account?{' '}
<Clerk.Link navigate="sign-in" className="font-bold underline underline-offset-2 hover:text-yellow-200">
Sign in
</Clerk.Link>
</p>
</SignUp.Step>
</SignUp.Root>
</div>
)
}
Comment on lines +2 to +117
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Multi‑step Clerk sign‑up flow is well structured; verify step/strategy names

The sign‑up page is nicely organized:

  • start step for email/password.
  • verifications step with email_code strategy.
  • continue step for username.
  • Consistent use of Clerk.GlobalError, Clerk.FieldError, and Clerk.Link for navigation.

Functionally this matches common Clerk Elements patterns.

Just ensure that:

  • Your Clerk instance is configured to use the email_code verification strategy, and
  • The step names ("start", "verifications", "continue") align with the expected flow configuration for the Elements sign‑up component in your version.

If needed, compare to Clerk’s Elements sign-up examples:


🌐 Web query:

Show an example multi-step email/password + email_code verification sign-up flow using @clerk/elements/sign-up, including the expected step names and `SignUp.Strategy` configuration.

💡 Result:

Below is a minimal multi-step email+password sign-up flow using @clerk/elements/sign-up that requires email verification (email_code). It shows the expected step names and how to configure the SignUp.Strategy blocks for verification.

Example (React / Clerk Elements)

  • expected step names: "start", "continue" (optional, when Clerk requires extra fields), "verifications".
  • verification strategies used inside the "verifications" step: SignUp.Strategy name="email_code" (and you can add phone_code, etc. if supported).

Code:
'use client'

import * as Clerk from '@clerk/elements/common'
import * as SignUp from '@clerk/elements/sign-up'

export default function SignUpPage() {
return (
<SignUp.Root>
{/* 1) initial sign-up form: collects email + password (and optional username/social) */}
<SignUp.Step name="start">

Create an account

    <Clerk.Field name="emailAddress">
      <Clerk.Label>Email</Clerk.Label>
      <Clerk.Input />
      <Clerk.FieldError />
    </Clerk.Field>

    <Clerk.Field name="password">
      <Clerk.Label>Password</Clerk.Label>
      <Clerk.Input type="password" />
      <Clerk.FieldError />
    </Clerk.Field>

    <SignUp.Action submit>Sign up</SignUp.Action>
  </SignUp.Step>

  {/* 2) optional: continue step for missing required fields (e.g., username) */}
  <SignUp.Step name="continue">
    <h2>More info</h2>
    <Clerk.Field name="username">
      <Clerk.Label>Username</Clerk.Label>
      <Clerk.Input />
      <Clerk.FieldError />
    </Clerk.Field>
    <SignUp.Action submit>Continue</SignUp.Action>
  </SignUp.Step>

  {/* 3) verifications: render the form(s) for the verification strategy(ies) */}
  <SignUp.Step name="verifications">
    {/* Email code verification */}
    <SignUp.Strategy name="email_code">
      <h2>Check your email</h2>
      <p>We sent a code to <SignUp.SafeIdentifier /></p>

      <Clerk.Field name="code">
        <Clerk.Label>Email code</Clerk.Label>
        <Clerk.Input />
        <Clerk.FieldError />
      </Clerk.Field>

      <SignUp.Action submit>Verify</SignUp.Action>
    </SignUp.Strategy>

    {/* (Optional) example phone_code strategy if configured */}
    <SignUp.Strategy name="phone_code">
      <h2>Check your phone</h2>
      <Clerk.Field name="code">
        <Clerk.Label>SMS code</Clerk.Label>
        <Clerk.Input />
        <Clerk.FieldError />
      </Clerk.Field>
      <SignUp.Action submit>Verify</SignUp.Action>
    </SignUp.Strategy>
  </SignUp.Step>
</SignUp.Root>

)
}

Notes / behavior

  • start: initial attempt creation (email+password submitted here). After creating the attempt Clerk will move to either "continue" (if more required fields) or "verifications".
  • continue: optional, used when Clerk indicates missing required user fields.
  • verifications: should contain a SignUp.Strategy block for each verification strategy you support (email_code is the one used for email OTP verification). Clerk will render only the strategy(ies) relevant to the current sign-up attempt. See SignUp.SafeIdentifier to show the masked email/phone. (Examples and component API documented by Clerk.) [1][2][3]

References

  • Clerk Elements sign-up examples and steps (start / continue / verifications) and SignUp.Strategy usage. [1][4]

Fix step ordering: continue must come before verifications

The step order is incorrect. Expected step names are "start", "continue" (optional, when Clerk requires extra fields), "verifications".

Your code currently sequences:

  1. start (email/password) ✓
  2. verifications (email_code) ✗ Should be third
  3. continue (username) ✗ Should be second

After creating the attempt Clerk will move to either "continue" (if more required fields) or "verifications". Move the continue step (with username) to appear between start and verifications steps.

🤖 Prompt for AI Agents
In app/(auth)/sign-up/[[...sign-up]]/page.tsx around lines 2 to 117, the
SignUp.Step ordering is wrong: the "continue" step (username) must appear
between "start" and "verifications". Move the entire SignUp.Step block with
name="continue" so it comes immediately after the "start" step and before the
"verifications" step, preserving its contents and classes; verify the
SignUp.Step blocks are now in order "start", "continue", "verifications".


16 changes: 13 additions & 3 deletions app/_components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"use client";
import Image from 'next/image'
import React from 'react'
import { Button } from "@/components/ui/button";
Expand All @@ -11,6 +12,7 @@ import {
NavigationMenuList,
NavigationMenuTrigger,
} from "@/components/ui/navigation-menu";
import { UserButton, useUser } from '@clerk/nextjs';

Comment on lines +15 to 16
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Tighten auth-based header logic and fix “Signup” vs /sign-in mismatch

A couple of small points around the auth UI:

  1. Label vs route mismatch (user-facing)
    The unauthenticated CTA shows “Signup” but navigates to /sign-in. Either:

    • Change the label to “Sign in”, or
    • Point the link to /sign-up so it matches the new sign‑up page.
  2. Use isSignedIn instead of checking user directly (cleaner semantics)
    useUser() exposes isSignedIn, which is clearer and avoids relying on user being truthy:

  • const{user}= useUser();
  • const { isSignedIn } = useUser();
    ...
  •  {!user? 
    
  •  <Link href={'/sign-in'}>
    
  •  <Button className="font-game text-2xl" variant="pixel">Signup</Button>
    
  •  </Link>
    
  •  :<div className='flex gap-4 items-center'>
    
  •  {!isSignedIn ? (
    
  •    <Link href="/sign-up">
    
  •      <Button className="font-game text-2xl" variant="pixel">Sign up</Button>
    
  •    </Link>
    
  •  ) : (
    
  •    <div className="flex gap-4 items-center">
       <Button className="font-game text-2xl" variant="pixel">Dashboard</Button>
       <UserButton/>
    
  •    </div>}
    
  •    </div>
    
  •  )}
    
    
    
  1. Optional: wire “Dashboard” to a route
    When you introduce your main authenticated landing page (e.g. /dashboard), consider turning the Dashboard button into a Link so it actually navigates.

For reference on useUser return shape and recommended usage, you can confirm against Clerk’s docs:

Also applies to: 78-134


🌐 Web query:

What does `useUser` from @clerk/nextjs return, and is `isSignedIn` the preferred flag for checking auth state?

💡 Result:

Short answer:

  • useUser() from @clerk/nextjs returns an object with (at least) isLoaded, isSignedIn and user (the current User resource). Use isLoaded to wait for Clerk to initialize, user for the UserResource, and isSignedIn to know whether a user is signed in. [1][2]

Is isSignedIn the preferred flag?

  • Yes — the docs show using isSignedIn (together with isLoaded) as the client-side boolean to guard protected UI. If you need IDs/sessions instead, Clerk also exposes useAuth / server helpers (auth(), currentUser(), getAuth(), clerkClient) for other contexts. [1][2][3]

Sources:
[1] Clerk useUser docs.
[2] Clerk "Read session and user data" guide.
[3] Clerk migration/example showing useAuth and useUser.


Based on the web search verification, I can confirm that Clerk's useUser() hook allows you to check if the user is signed in through the isSignedIn property, which returns true if the user is signed in. The Clerk documentation consistently demonstrates using isLoaded and isSignedIn properties to handle the loading state and check if the user is signed in, making this a documented best practice.

However, I need to examine the actual codebase to verify the specific issues mentioned in the review comment regarding the label/route mismatch and current implementation. Let me check the Header.tsx file:


Since the codebase wasn't available, I'll need to request direct verification:



Verify the actual Header.tsx implementation against the two issues identified

The review recommendations are validated by Clerk's official documentation:

  1. Using isLoaded and isSignedIn properties is the recommended approach for checking authentication state
  2. The label vs. route mismatch ("Signup" button pointing to /sign-in instead of /sign-up) should be corrected for consistency

However, since I cannot access the actual codebase to confirm whether these issues currently exist in your Header.tsx, please verify:

  • Does your current code check !user or !isSignedIn?
  • Does the unauthenticated CTA label match its destination route?

If these issues are present, apply the refactored code shown in the review comment. If already corrected, the review comment can be dismissed.


🏁 Script executed:

#!/bin/bash
# Find and examine Header.tsx file, particularly around the mentioned line ranges
find . -name "Header.tsx" -o -name "header.tsx" | head -5

Length of output: 28


🏁 Script executed:

#!/bin/bash
# Search for Header component files
fd -e tsx -e ts -e jsx -e js | grep -i header | head -10

Length of output: 26



---

🏁 Script executed:

```shell
#!/bin/bash
# Examine the Header.tsx file content
cat ./app/_components/Header.tsx

Length of output: 4309


Fix auth-check semantics and align button label with route

Both issues identified in the review are confirmed in the code:

  1. Label/route mismatch at line 119: Button text is "Signup" but href={'/sign-in'} should be href="/sign-up" to match the label, or change the label to "Sign in".

  2. Using user directly instead of isSignedIn at lines 78 and 117: Per Clerk's official documentation, isSignedIn is the preferred flag for checking auth state. Change const{user}= useUser(); to const { isSignedIn } = useUser(); and update the conditional from {!user? to {!isSignedIn?.

Apply the refactored code pattern shown in the original review. The optional Dashboard route linking suggestion remains valid for future enhancement.

const courses = [
{
Expand Down Expand Up @@ -72,6 +74,9 @@ const courses = [


function Header() {

const{user}= useUser();

return (
<div className="p-4 max-w-7xl mx-auto flex justify-between items-center w-full">
<div className="flex gap-2 items-center">
Expand Down Expand Up @@ -119,9 +124,14 @@ function Header() {
</NavigationMenuList>
</NavigationMenu>

<Button className="font-game text-2xl" variant="pixel">
Signup
</Button>
{!user?
<Link href={'/sign-in'}>
<Button className="font-game text-2xl" variant="pixel">Signup</Button>
</Link>
:<div className='flex gap-4 items-center'>
<Button className="font-game text-2xl" variant="pixel">Dashboard</Button>
<UserButton/>
</div>}
</div>
)
}
Expand Down
4 changes: 3 additions & 1 deletion app/_components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import Image from 'next/image'
import { Button } from '@/components/ui/button'
import Link from "next/link";

function Hero() {
return (
Expand All @@ -12,8 +13,9 @@ function Hero() {
<h2 className='font-bold text-7xl font-game text-yellow-400'>Coding Adventure</h2>

<h2 className='mt-5 font-game text-3xl'> Beginner friendly coding course and Projects </h2>

<Link href={'/sign-in'}>
<Button className='font-game text-3xl p-6 mt-7' variant={"pixel"}>Get Started</Button>
</Link>
</div>
</div>
)
Expand Down
3 changes: 3 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { Geist, Geist_Mono, Inter, Pixelify_Sans,Jersey_10 } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "next-themes";
import {ClerkProvider} from '@clerk/nextjs'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

ClerkProvider wrapping looks correct; ensure configuration/env are set

Wrapping the root layout with <ClerkProvider> so all children get auth context is aligned with Clerk’s App Router patterns. No issues with the placement relative to <html> and your ThemeProvider.

Just make sure the required Clerk env vars (e.g. NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, and any domain URLs) are configured for all environments (dev, preview, prod).

You can cross‑check against Clerk’s latest Next.js App Router setup guide for ClerkProvider props and required env vars.

Also applies to: 39-55


🌐 Web query:

Show the recommended app/layout.tsx setup for ClerkProvider when using @clerk/nextjs 6.35.4 with the Next.js App Router.

💡 Result:

Recommended setup — create a small client wrapper that renders ClerkProvider, then use it in your root app/layout.tsx so the App Router keeps the root layout as a server component while Clerk runs as a client component.

  1. app/components/ClerkProviderClient.tsx
    (use a client component to host ClerkProvider)
'use client';

import { ClerkProvider } from '@clerk/nextjs';
import React from 'react';

export default function ClerkProviderClient({ children }: { children: React.ReactNode }) {
  return <ClerkProvider>{children}</ClerkProvider>;
}
  1. app/layout.tsx
    (root layout remains a server component)
import './globals.css';
import ClerkProviderClient from '@/app/components/ClerkProviderClient';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <ClerkProviderClient>{children}</ClerkProviderClient>
      </body>
    </html>
  );
}

Notes:

  • This keeps the root layout as a server component while correctly mounting Clerk on the client. See Clerk's App Router guidance and ClerkProvider usage for the recommended pattern. [1][2]

Sources:
[1] Clerk — Next.js Quickstart (App Router) example.
[2] Clerk — usage guidance.


🏁 Script executed:

#!/bin/bash
# Examine the full app/layout.tsx to understand ClerkProvider usage and component type
cat app/layout.tsx

Length of output: 1290


ClerkProvider requires refactoring to use a 'use client' wrapper component

The current implementation directly wraps the root layout with <ClerkProvider>, but Clerk's official documentation for @clerk/nextjs 6.35.4 recommends a different pattern. Since your root layout is a server component (it exports metadata), it should not directly use ClerkProvider, which is a client component. This can cause hydration mismatches or context errors.

Required refactoring:

  1. Create app/components/ClerkProviderClient.tsx as a 'use client' component:

    'use client';
    import { ClerkProvider } from '@clerk/nextjs';
    export default function ClerkProviderClient({ children }: { children: React.ReactNode }) {
      return <ClerkProvider>{children}</ClerkProvider>;
    }
  2. Update app/layout.tsx to use the wrapper instead of directly wrapping with <ClerkProvider>:

    import ClerkProviderClient from '@/app/components/ClerkProviderClient';
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en" suppressHydrationWarning className="dark">
          <body>
            <ClerkProviderClient>
              <ThemeProvider>
                {children}
              </ThemeProvider>
            </ClerkProviderClient>
          </body>
        </html>
      );
    }

Also ensure required Clerk env vars (NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY) are configured.

🤖 Prompt for AI Agents
In app/layout.tsx around line 5, the root layout (a server component exporting
metadata) directly imports and uses ClerkProvider (a client component), which
causes hydration/context issues; fix by creating a new client component file
app/components/ClerkProviderClient.tsx with "use client" that imports
ClerkProvider and renders children, then update app/layout.tsx to import and
wrap children with ClerkProviderClient instead of ClerkProvider; also verify
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY are set in env.


const geistSans = Geist({
variable: "--font-geist-sans",
Expand Down Expand Up @@ -35,6 +36,7 @@ export default function RootLayout({
children: React.ReactNode;
}) {
return (
<ClerkProvider>
<html lang="en" suppressHydrationWarning className="dark">
<body
className={`${geistSans.variable} ${geistMono.variable} ${gameFont.variable} ${inter.variable} antialiased`}
Expand All @@ -49,5 +51,6 @@ export default function RootLayout({
</ThemeProvider>
</body>
</html>
</ClerkProvider>
);
}
21 changes: 21 additions & 0 deletions middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'

const isPublicRoute = createRouteMatcher([
'/sign-in(.*)',
'/sign-up(.*)','/'
])

export default clerkMiddleware(async (auth, req) => {
if (!isPublicRoute(req)) {
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)(.*)',
],
}
Loading