Clerk.js provides authentication and user management for web applications. In a Next.js AI application, it handles sign-in and onboarding while the application decides which routes to protect and how much access a signed-in user receives. Built-in MFA is available when stronger account protection is needed. section 9.3 section 9.3.1
A practical Next.js setup has three parts:
- Create a Clerk project, choose sign-in methods, install @clerk/nextjs, and configure the Clerk environment keys. section 9.3.1
- Use Clerk middleware to protect /chat. Redirect visitors from the index page to /sign-in or, when signed in, /chat. section 9.3.1
- Apply application-specific limits separately: the example caps authenticated users at ten messages per day with Upstash Redis. section 9.3.1
Listing 9.3 Configuring Clerk middleware
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server"; #1
const isProtectedRoute =
createRouteMatcher(["/chat(.*)"]); #2
export default clerkMiddleware(async (auth, req) => {
if (isProtectedRoute(req)) await auth.protect();
const corsResponse = handleCORS(req);
if (corsResponse instanceof NextResponse) {
return corsResponse;
}
const rateLimitResponse = rateLimit(req);
if (rateLimitResponse instanceof NextResponse) {
return rateLimitResponse;
}
return NextResponse.next();
});
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)(.*)',
]
};
The middleware example matches /chat routes and calls auth.protect() for them; it also incorporates CORS and rate-limit handling. section 9.3.1
Listing 9.4 Redirecting to authentication page if not signed in
'use client';
import { useUser } from "@clerk/nextjs";
import { useRouter } from 'next/navigation'; // Changed import
import { useEffect } from 'react';
export default function IndexPage() {
const { isSignedIn } = useUser(); #1
const router = useRouter(); #2
useEffect(() => {
if (!isSignedIn) {. #3
router.push('/sign-in');
} else {
router.push('/chat')
}
}, [isSignedIn, router]);
return (
<div>
Loading...
</div>
);
}
The index-page example uses Clerk’s useUser hook and the Next.js router to choose the sign-in or chat destination. section 9.3.1
Authenticated AI features
An interview assistant requires sign-in before a user starts a session; authentication supports user-associated session storage in Redis and control over API credit usage. A RAG application likewise requires sign-in before chat and uses authentication to restrict document uploads and access. Authentication sits alongside, rather than replaces, file validation, rate limits, and other safeguards. section 10.1.1 section 11.1.1 section 11.2.2
