diff --git a/src/layout/AuthProvider/Clerk/index.tsx b/src/layout/AuthProvider/Clerk/index.tsx index 05531ff4a1cfb..ff6e798973337 100644 --- a/src/layout/AuthProvider/Clerk/index.tsx +++ b/src/layout/AuthProvider/Clerk/index.tsx @@ -1,7 +1,7 @@ 'use client'; import { ClerkProvider } from '@clerk/nextjs'; -import { PropsWithChildren, memo, useMemo } from 'react'; +import { PropsWithChildren, memo, useEffect, useMemo, useState, useTransition } from 'react'; import { useTranslation } from 'react-i18next'; import UserUpdater from './UserUpdater'; @@ -15,6 +15,18 @@ const Clerk = memo(({ children }: PropsWithChildren) => { const localization = useMemo(() => getResourceBundle(language, 'clerk'), [language]); + // When useAppearance returns different result during SSR vs. client-side (when theme mode is auto), the appearance is not applied + // It's because Clerk internally re-applies SSR props after transition which overrides client-side props, see https://github.com/clerk/javascript/blob/main/packages/nextjs/src/app-router/client/ClerkProvider.tsx + // This re-renders the provider after transition to make sure client-side props are always applied + const [, setCount] = useState(0); + const [isPending, startTransition] = useTransition(); + useEffect(() => { + if (isPending) return; + startTransition(() => { + setCount((count) => count + 1); + }); + }, [isPending, startTransition]); + return ( {children}