skip to Main Content

Question:

I’m working with Next.js and using Clerk for authentication alongside the Convex client. I encountered this error:

Error: Clerk: useAuth() called in static mode, wrap this component in <ClerkProvider dynamic> to make auth data available during server-side rendering.

I tried wrapping the component in <ClerkProvider dynamic>, as the error suggested, and also added "use client" at the top of the file. However, I’m still getting the error.

Here’s my setup:

  1. Provider and Layout Setup:

    I’m using ConvexProviderWithClerk along with ClerkProvider to pass useAuth for authentication.

    Below is my ConvexClientProvider component:

    import { ClerkProvider, useAuth } from "@clerk/nextjs";
    import { ConvexProviderWithClerk } from "convex/react-clerk";
    import { ConvexReactClient } from "convex/react";
    
    interface ConvexClientProviderProps {
        children: React.ReactNode;
    }
    
    const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY!;
    const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL!;
    const convex = new ConvexReactClient(convexUrl);
    
    export const ConvexClientProvider = ({ children }: ConvexClientProviderProps) => {
        return (
            <ClerkProvider publishableKey={PUBLISHABLE_KEY}>
                <ConvexProviderWithClerk useAuth={useAuth} client={convex}>
                    {children}
                </ConvexProviderWithClerk>
            </ClerkProvider>
        );
    };
    
  2. Root Layout Component:

    Here’s the structure of my RootLayout component, which wraps the app in ConvexClientProvider:

    import { Metadata } from "next";
    import localFont from "next/font/local";
    import "./globals.css";
    import { ConvexClientProvider } from "@/providers/convex-client-provider";
    
    export const metadata: Metadata = {
        title: "Create Next App",
        description: "Generated by create next app",
    };
    
    export default function RootLayout({
        children,
    }: {
        children: React.ReactNode;
    }) {
        return (
            <html lang="en">
                <body>
                    <ConvexClientProvider>{children}</ConvexClientProvider>
                </body>
            </html>
        );
    }
    

Things I’ve Tried:

  1. Adding "use client" at the top of the RootLayout file and ConvexClientProvider.
  2. Wrapping the ConvexClientProvider with <ClerkProvider dynamic> as suggested in the error message.

2

Answers


  1. You need to import ClerkProvider,useAuth from "@clerk/clerk-react";

    import { ClerkProvider, useAuth } from "@clerk/clerk-react";

    It is mentioned here in convex docs:
    https://docs.convex.dev/auth/clerk

    Login or Signup to reply.
  2. I had the same issue. This resolved mine. Use dynamic import for ConvexProviderWithClerk. Enjoy!

    https://github.com/jeremy-clerk/clerk-auth-convex-chat/blob/upgrade/providers/ConvexClientProvider.tsx

    Source:https://discord.com/channels/856971667393609759/1304189273553109022/1304579659677040660

    The cause explained in Clerk Discord:

    We don’t expect you to need to wrap most third-party components since it’s likely you’ll be using them within Client Components. However, one exception is >providers, since they rely on React state and context, and are typically needed at the root of an application. Learn more about third-party context providers below.

    https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#using-context-providers

    The problem is that the ConvexProvider takes in the useAuth() hook and NextJS is trying to statically render that provider. We now statically render the <ClerkProvider /> by default – unless you pass the dynamic prop – buuuttt – the problem is that Convex is still trying to statically render, even though it’s within a client boundary. It could be the way they’re doing imports or the way NextJS is trying to resolve packages.

    It seems like it stems from nesting the Context Providers. If Convex added the "use client"; directive – this should be fixed. When I downgraded the packages, it changes to Clerk rendering dynamically by default, which forces everything underneath it to be dynamically rendered. It should be noted that the "use client"; directive just means that the code will be included in the Client bundle – it can still be evaluated by NextJS.

    What I did, was to use an older school method called a "dynamic import" by doing this with the ssr: false option – I forced NextJS to not evaluate the import until the page loads – which resolves our issue of Convex throwing throwing the error about useAuth(). This is the error that I was finding in the server logs:

    Error: Clerk: useAuth() called in static mode, wrap this component in <ClerkProvider dynamic> to make auth data available during server-side rendering.

    Which came from the server – and we were wrapping it in a <ClerkProvider dynamic> but for whatever reason, it was still trying to eval this.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search