authenticationnext.jsclerk

Clerk 404 when signing out from a protected page (Next.js)


I have the following middleware:

import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const publicRoutes = [
  '/',
  '/browse',
  '/sign-in(.*)',
  '/sign-up(.*)',
];

const isPublicRoute = createRouteMatcher(publicRoutes);

export default clerkMiddleware(
  (auth, request) => {
    if (!isPublicRoute(request)) {
      auth().protect();
    }
  },
  { debug: true }
);

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

Now, let's say that I have a protected route /dashboard. My issue is that if I am signed in, and if I am on the /dashboard page, and I click Sign Out via Clerk's built in <UserButton />, for a fraction of a second I see a 404 (and there's a POST request to /dashboard as well) before I am redirected to /.

Any suggestions? I understand why I'm getting the 404 but I fail to fix the issue.


Solution

  • As it turns out there are multiple discussions about this on the Clerk Discord. Sadly, the documentation has this information rather obfuscated, but the solution - in my case - was to extend my middleware.ts with the following:

    export default clerkMiddleware(
      (auth, request) => {
      if (!auth().userId && !isPublicRoute(request)) {
        return auth().redirectToSignIn();
      }
      // rest of the middleware
    }
    

    This seemed to have done the job...