Clerk's Next.js SDK gives you access to prebuilt components, hooksNext.js Icon, and helpersNext.js Icon for Next.js Server Components, Route Handlers and Middleware. Run the following command to install it:
Remove the <SessionProvider session={session}> provider from Auth.js and replace it with <ClerkProvider>.
The <ClerkProvider> component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with <ClerkProvider> to make authentication globally accessible. See the reference docs for other configuration options.
Account Portal is the fastest way to authenticate your app. Clerk's Account Portal hosts the <SignIn />, <SignUp />, <UserProfile />, and other components for your application. Read more about Account Portal.
To use the Account Portal, remove the routes that mount the Auth.js sign-in and sign-up UI. Replace the links to those routes with the <SignInButton> or <SignUpButton> components.
With Clerk, you can control access to your application in a few different ways. One way is to use Clerk's Middleware to protect your entire application, or specific routes. Another way is to use Clerk's components to conditionally render UI based on the user's authentication state. You can hide or show UI based on whether the user is signed in or not.
You will need to remove the Auth.js Middleware from your application, and replace it with the Clerk's Middleware helper, clerkMiddleware().
Auth.js's middleware always rejects unauthorized requests. You may have additionally configured the Next.js middleware config to protect specific private routes. You will need to make note of this configuration so you can recreate it.
Clerk's Middleware gives you fine-grained control over handling the authenticated state and will, by default, run for your entire application.
The example below is a basic configuration that does not protect any routes. All routes are public and you must opt-in to protection for routes. Read the clerkMiddleware()Next.js Icon documentation to learn more about how you can configure your Middleware.
middleware.ts
import { clerkMiddleware } from'@clerk/nextjs/server'exportdefaultclerkMiddleware()exportconstconfig= { matcher: ['/((?!.*\\..*|_next).*)',// Don't run middleware on static files'/',// Run middleware on index page'/(api|trpc)(.*)',// Run middleware on API routes ],}
To conditionally render UI when the user is signed in, wrap it with <SignedIn>.
To conditionally render UI when the user is not signed in, wrap it with <SignedOut>.
app/page.tsx
import { SignedIn, SignedOut } from'@clerk/nextjs'exportdefaultfunctionHome() {return ( <div> <SignedOut> <p>This content is public. Only signed out users can see this.</p> </SignedOut> <SignedIn> <p>This content is private. Only signed in users can see this.</p> </SignedIn> </div> )}
Replace Auth.js's useSession() hook with Clerk's hooks.
The useAuth() hook can be used to retrieve basic authentication information. The useUser() hook can be used to retrieve the full UserJavaScript Icon object, which includes information about the user, such as their first name, emails, phone numbers, and more.
When you migrate to Clerk, you will likely need to resolve the foreign key that you used in your database. If you used the userId from NextAuth.js, you could resolve this issue with one of the following two options:
When you migrate user data from Auth.js to Clerk, Clerk generates new user IDs for each user. If you are using existing user IDs as foreign keys in your database (e.g. in a user_id column), you can save those IDs as the user's externalId in Clerk. This externalId can be included in the session token by adding the following customization. The following example will set the user's ID to be externalId if one is present, otherwise, it will use the Clerk's user ID.
{"userId":"{{user.external_id || user.id}}"}
App Router
Pages Router
To access the userId from the session claims, you can use the auth() helper.
app/page.tsx
import { auth } from'@clerk/nextjs/server'exportdefaultasyncfunctionPage() {const { sessionClaims } =awaitauth()if (!sessionClaims) {return <p>Not signed in</p> }constuserId=sessionClaims.subreturn <p>Welcome user {userId}</p>}
To access the userId from the session claims, you can use the getAuth() helper.
pages/index.tsx
import { getAuth, buildClerkProps } from'@clerk/nextjs/server'import { GetServerSideProps } from'next'exportconstgetServerSideProps:GetServerSideProps=async (ctx) => {const { userId } =getAuth(ctx.req)if (!userId) {// handle user is not signed in. }const { sessionClaims: { userId }, } =getAuth(req)console.log(userId)return { props: { ...buildClerkProps(ctx.req) } }}
Note
You can not access the above from the client-side. If you are using one of Clerk's hooks, then you will need to check if externalID exists. If it doesn't, then read the userId.
Every Clerk application has a Development and a Production instance. Before you start migrating user data, you need to configure your Clerk Production instance and migrate your Auth.js users directly into that instance. The Deploying to Production page covers creating a Production instance.
You can migrate a small set of users on the Development instance for testing/staging. To enable importing users to your Development instance, add IMPORT_TO_DEV_INSTANCE=true to the .env for the migration script.
If you already have an API endpoint in your Auth.js app that returns a list of users, you can use that. Otherwise, you will need to query your database to obtain the user information, or use an export function from a database management tool.
The example below is a SQL query that would return the user information in the correct format for the migration script.
SELECT id as userId, email, nameFROM users
Edit the .env. file in the migration, and add your Clerk Secret Key using CLERK_SECRET_KEY
Run the script with npm start
Check that your users are listed on the Users page in the Clerk Dashboard. If the users appear to have imported correctly, verify by signing in to your application secured by Clerk with your user account.
Check for an error log for any users that were not migrated successfully.
This guide covers the most common steps that you would take for the migration. If you have more complex integrations with Auth.js that are not covered here, don't hesitate to reach out in the Clerk Discord by creating a post in the Support channel.