sanityclerknext.js15

Clerk + Sanity integration issue w/ Next.js


Using Next.js (15.2.4), Clerk Auth, and trying to integrate Sanity as a CMS into the application. After installing Sanity and hitting /studio, this error appears:

Error: Clerk: auth() was called, but Clerk can't detect usage of clerkMiddleware(). Please ensure the following:

- Your Middleware exists at ./src/middleware.(ts|js)
- clerkMiddleware() is used in your Next.js Middleware.
- Your Middleware matcher is configured to match this route or page.
- If you are using the src directory, make sure the Middleware file is inside of it.

For more details, see https://clerk.com/docs/quickstarts/nextjs

Error snapshot

middleware.ts

import { clerkMiddleware } from "@clerk/nextjs/server";

export default clerkMiddleware();

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)(.*)",
  ],
};

Call Stack

resolveErrorDev
node_modules/.pnpm/next@15.2.4_@babel+core@7.28.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js (1845:1)
processFullStringRow
node_modules/.pnpm/next@15.2.4_@babel+core@7.28.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js (2225:1)
processFullBinaryRow
node_modules/.pnpm/next@15.2.4_@babel+core@7.28.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js (2213:1)
progress
node_modules/.pnpm/next@15.2.4_@babel+core@7.28.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js (2459:1)

Solution

  • Avoid using <ClerkProvider> wrapper at the root of your layout, for Sanity studio brings its own auth layer.

    export default function RootLayout() {
      return (
        <ClerkProvider>
          <html lang="en" suppressHydrationWarning>
            <body>
              <ThemeProvider>
                <header>
                  <SignedOut>
                    <div>
                      <SignInButton />
                    </div>
                  </SignedOut>
                  <SignedIn>
                    <NavBar></NavBar>
                  </SignedIn>
                </header>
                <main>{children}</main>
                <Footer></Footer>
              </ThemeProvider>
            </body>
          </html>
        </ClerkProvider>
      );
    }
    

    Try this instead:

    export default function RootLayout() {
      return (
        <html lang="en" suppressHydrationWarning>
          <body>
            <ThemeProvider>
              <ClerkProvider>
                {/* Avoid using `<ClerkProvider>` wrapper at the root of your layout, for _Sanity_ studio brings its own auth layer. */}
                <NavBar></NavBar>
              </ClerkProvider>
              <main>{children}</main>
              {/* <Footer></Footer> */}
            </ThemeProvider>
          </body>
        </html>
      );
    }
    

    Note: Do not move <ClerkProvider> into NavBar, for it causes layout thrashing .)