fix(frontend): keep Clerk enabled check in sync with AuthProvider

This commit is contained in:
Ishan (OpenClaw)
2026-02-07 09:05:39 +00:00
parent 2c13c5b5ce
commit 71e291edd8
2 changed files with 21 additions and 20 deletions

View File

@@ -17,11 +17,26 @@ import {
import type { ComponentProps } from "react"; import type { ComponentProps } from "react";
export function isValidClerkPublishableKey(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.
//
// Note: Clerk appears to validate key *contents*, not just shape. We therefore
// use a conservative heuristic to avoid treating obvious placeholders as valid.
const m = /^pk_(test|live)_([A-Za-z0-9]+)$/.exec(key);
if (!m) return false;
const body = m[2];
if (body.length < 16) return false;
if (/^0+$/.test(body)) return false;
return true;
}
export function isClerkEnabled(): boolean { export function isClerkEnabled(): boolean {
// Invariant: Clerk is disabled ONLY when the publishable key is absent. // IMPORTANT: keep this in sync with AuthProvider; otherwise components like
// If a key is present, we assume Clerk is intended to be enabled and we let // <SignedOut/> may render without a <ClerkProvider/> and crash during prerender.
// Clerk fail fast if the key is invalid/misconfigured. return isValidClerkPublishableKey(process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY);
return Boolean(process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY);
} }
export function SignedIn(props: { children: ReactNode }) { export function SignedIn(props: { children: ReactNode }) {

View File

@@ -3,26 +3,12 @@
import { ClerkProvider } from "@clerk/nextjs"; import { ClerkProvider } from "@clerk/nextjs";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
function isLikelyValidClerkPublishableKey(key: string | undefined): key is string { import { isValidClerkPublishableKey } from "@/auth/clerk";
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.
//
// Note: Clerk appears to validate key *contents*, not just shape. We therefore
// use a conservative heuristic to avoid treating obvious placeholders as valid.
const m = /^pk_(test|live)_([A-Za-z0-9]+)$/.exec(key);
if (!m) return false;
const body = m[2];
if (body.length < 16) return false;
if (/^0+$/.test(body)) return false;
return true;
}
export function AuthProvider({ children }: { children: ReactNode }) { export function AuthProvider({ children }: { children: ReactNode }) {
const publishableKey = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY; const publishableKey = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY;
if (!isLikelyValidClerkPublishableKey(publishableKey)) { if (!isValidClerkPublishableKey(publishableKey)) {
return <>{children}</>; return <>{children}</>;
} }