Docs

Upgrade to @clerk/nextjs v6

To upgrade to @clerk/nextjs v6, use the upgrade CLI:

terminal
npx @clerk/upgrade

The CLI will walk you through the upgrade and apply necessary changes to your application automatically.

auth() is now async

To support Next.js's change to async dynamic APIs, auth() is now asynchronous. The codemod will migrate this for you.

import { auth } from '@clerk/nextjs/server';

export function GET() {
 const { userId } = auth();
export async function GET() {
 const { userId } = await auth();

return new Response(JSON.stringify({ userId }));
}

In clerkMiddleware

Now that auth() is asynchronous, custom middleware handlers that rely on auth() must also now be converted to be asynchronous. The codemod will migrate this for you.

import { clerkClient, clerkMiddleware } from '@clerk/nextjs/server';
import { NextResponse } from 'next/server';

export default clerkMiddleware((auth, request) => {
 const resolvedAuth = auth();
export default clerkMiddleware(async (auth, request) => {
 const resolvedAuth = await auth();

const count = await resolvedAuth.users.getCount();

if (count) {
  return NextResponse.redirect(new URL('/new-url', request.url));
}
});

export const config = {
matcher: [...],
};

clerkClient() is now async

Previously the clerkClient() method from @clerk/nextjs/server was synchronous, it is now asynchronous.

import { clerkClient, clerkMiddleware } from '@clerk/nextjs/server';
import { NextResponse } from 'next/server';

export default clerkMiddleware((auth, request) => {
 const client = clerkClient();
export default clerkMiddleware(async (auth, request) => {
 const client = await clerkClient();

const count = await client.users?.getCount();

if (count) {
  return NextResponse.redirect(new URL('/new-url', request.url));
}
});

export const config = {
matcher: [...],
};

auth().protect() is now auth.protect()

To ease calling of protect(), it is now accessible on the auth export, instead of from the return value.

import { auth } from '@clerk/nextjs/server'

export default function Page() {
  auth().protect()
export default async function Page() {
  await auth.protect()
}

Static rendering by default

Starting with v6, <ClerkProvider> will no longer opt your entire application into dynamic rendering by default. If this behavior is still desired, pass the dynamic prop to your root <ClerkProvider>:

import { ClerkProvider } from '@clerk/nextjs'

export default function RootLayout({ children }) {
return (
  <ClerkProvider>
  <ClerkProvider dynamic>
    <html>
      <body>{children}</body>
    </html>  
  </ClerkProvider>
)
}

Note that this isn't recommended, and in most cases you should use auth() to access auth data at request time instead. For more information, see the guide on Next.js rendering modes and Clerk.

Removed deprecated APIs

The following deprecated APIs have been removed.

  • authMiddleware() - Migrate to clerkMiddleware()
  • redirectToSignIn() - Migrate to const { redirectToSignIn } = await auth()
  • redirectToSignUp() - Migrate to const { redirectToSignUp } = await auth()
  • clerkClient - Migrate to await clerkClient()

Feedback

What did you think of this content?

Last updated on