diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index 146d8a1..905dfae 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -3,9 +3,9 @@ import "./globals.css";
import type { Metadata } from "next";
import type { ReactNode } from "react";
-import { ClerkProvider } from "@clerk/nextjs";
import { IBM_Plex_Sans, Sora } from "next/font/google";
+import { AuthProvider } from "@/components/providers/AuthProvider";
import { QueryProvider } from "@/components/providers/QueryProvider";
export const metadata: Metadata = {
@@ -29,14 +29,14 @@ const headingFont = Sora({
export default function RootLayout({ children }: { children: ReactNode }) {
return (
-
-
-
+
+
+
{children}
-
-
-
+
+
+
);
}
diff --git a/frontend/src/components/providers/AuthProvider.tsx b/frontend/src/components/providers/AuthProvider.tsx
new file mode 100644
index 0000000..03ceb00
--- /dev/null
+++ b/frontend/src/components/providers/AuthProvider.tsx
@@ -0,0 +1,22 @@
+"use client";
+
+import { ClerkProvider } from "@clerk/nextjs";
+import type { ReactNode } from "react";
+
+function isLikelyValidClerkPublishableKey(key: string | undefined): key is string {
+ if (!key) return false;
+ // Clerk publishable keys look like: pk_test_... or pk_live_...
+ // In CI we want builds to stay secretless; if the key isn't present/valid,
+ // we skip Clerk entirely so `next build` can prerender.
+ return /^pk_(test|live)_[A-Za-z0-9]+$/.test(key);
+}
+
+export function AuthProvider({ children }: { children: ReactNode }) {
+ const publishableKey = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY;
+
+ if (!isLikelyValidClerkPublishableKey(publishableKey)) {
+ return <>{children}>;
+ }
+
+ return {children};
+}