After installing Next.js 14 for my project, I decided to set up authentication with Clerk before getting started. Despite configuring the middleware.ts
and layout.tsx
files and running npm run dev
, the terminal showed that the /middleware
was compiled. However, upon accessing localhost:3000
in my browser, instead of redirecting to the Clerk sign-in page, it opened the Next.js layout page.
Here is the code snippet:
layout.tsx
:
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { ClerkProvider } from "@clerk/nextjs";
const inter = Inter({
subsets: ["latin"],
display: "swap",
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<ClerkProvider>
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
</ClerkProvider>
);
}
middleware.ts
:
import {clerkMiddleware, createRouteMatcher} from "@clerk/nextjs/server";
const isDashboardRoute = createRouteMatcher(["/dashboard(.)"]);
const isAdminRoute = createRouteMatcher(["/admin(.)"]);
export default clerkMiddleware((auth, req) => {
try {
// Restrict admin route to users with a specific role
if (isAdminRoute(req)) {
auth().protect({role: "org:admin"});
} else if (isDashboardRoute(req)) {
// Restrict dashboard routes to signed-in users
auth().protect();
} else {
// For all other routes, ensure the user is signed in
auth().protect();
}
} catch (e) {
auth().redirectToSignIn();
}
});
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)(.*)",
],
};
I am currently building a project clone where the tutorial used the deprecated authMiddleware to configure Clerk authentication in Next.js. I have followed the migration to clerkMiddleware but still face redirection issues.
Here is my old middleware code:
import { authMiddleware, redirectToSignIn } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
export default authMiddleware({
async afterAuth(auth, request) {
if(!auth.userId && !auth.isPublicRoute){
return redirectToSignIn({ returnBackUrl: request.url });
};
return NextResponse.next();
},
});
export const config = {
matcher: [
'/((?!.+\\.[\\w]+s|_next).*)',
'/(apis||trpcs)(.*)',
],
};