Setup Fullstack Authentication with Next.js, Auth.js, and Cloudflare D1
In this tutorial, you will build a Next.js app with authentication powered by Auth.js, Resend, and Cloudflare D1.
Before continuing, make sure you have a Cloudflare account and have installed and authenticated Wrangler ↗. Some experience with HTML, CSS, and JavaScript/TypeScript is helpful but not required. In this tutorial, you will learn:
- How to create a Next.js application and run it on Cloudflare Workers
- How to bind a Cloudflare D1 database to your Next.js app and use it to store authentication data
- How to use Auth.js to add serverless fullstack authentication to your Next.js app
You can find the finished code for this project on GitHub ↗.
- Sign up for a Cloudflare account ↗.
- Install
Node.js
↗.
Node.js version manager
Use a Node version manager like Volta ↗ or nvm ↗ to avoid permission issues and change Node.js versions. Wrangler, discussed later in this guide, requires a Node version of 16.17.0
or later.
- Create or login to a Resend account ↗ and get an API key ↗.
- Install and authenticate Wrangler.
From within the repository or directory where you want to create your project run:
For setup, select the following options:
- For What would you like to start with?, choose
Framework Starter
. - For Which development framework do you want to use?, choose
Next.js
. - Complete the framework's own CLI wizard.
- For Do you want to use git for version control?, choose
Yes
. - For Do you want to deploy your application?, choose
No
(we will be making some changes before deploying).
This will create a new Next.js project using OpenNext ↗ that will run in a Worker using Workers Static Assets.
Before we get started, open your project's tsconfig.json
file and add the following to the compilerOptions
object to allow for top level await needed to let our application get the Cloudflare context:
Throughout this tutorial, we'll add several values to Cloudflare Secrets. For local development, add those same values to a file in the top level of your project called .dev.vars
and make sure it is not committed into version control. This will let you work with Secret values locally. Go ahead and copy and paste the following into .dev.vars
for now and replace the values as we go.
Following the installation instructions ↗ from Auth.js, begin by installing Auth.js:
Now run the following to generate an AUTH_SECRET
:
Now, deviating from the standard Auth.js setup, locate your generated secret (likely in a file named .env.local
) and add the secret to your Workers application by running the following and completing the steps to add a secret's value that we just generated:
After adding the secret, update your .dev.vars
file to include an AUTH_SECRET
value (this secret should be different from the one you generated earlier for security purposes):
Next, go into the newly generated env.d.ts
file and add the following to the CloudflareEnv interface:
Now, install the Auth.js D1 adapter by running:
Create a D1 database using the following command:
When finished you should see instructions to add the database binding to your wrangler.toml
. Example binding:
Now, within your env.d.ts
, add your D1 binding, like:
Auth.js provides integrations for many different credential providers ↗ such as Google, GitHub, etc. For this tutorial we're going to use Resend for magic links ↗. You should have already created a Resend account and have an API key ↗.
Using either a Resend verified domain email address ↗ or onboarding@resend.dev
, add a new Secret to your Worker containing the email your magic links will come from:
Next, ensure the AUTH_EMAIL_FROM
environment variable is updated in your .dev.vars
file with the email you just added as a secret:
Now create a Resend API key ↗ with Sending access
and add it to your Worker's Secrets:
As with previous secrets, update your .dev.vars
file with the new secret value for AUTH_RESEND_KEY
to use in local development:
After adding both of those Secrets, your env.d.ts
should now include the following:
Credential providers and database adapters are provided to Auth.js through a configuration file called auth.ts
. Create a file within your src/app/
directory called auth.ts
with the following contents:
Now, lets add the route handler and middleware used to authenticate and persist sessions.
Create a new directory structure and route handler within src/app/api/auth/[...nextauth]
called route.ts
. The file should contain:
Now, within the src/
directory, create a middleware.ts
file to persist session data containing the following:
The D1 adapter requires that tables be created within your database. It recommends ↗ using the exported up()
method to complete this. Within src/app/api/
create a directory called setup
containing a file called route.ts
. Within this route handler, add the following code:
You'll need to run this once on your production database to create the necessary tables. If you're following along with this tutorial, we'll run it together in a few steps.
Before we go further, make sure you've created all of the necessary files:
Directorysrc/
Directoryapp/
Directoryapi/
Directoryauth/
Directory[...nextauth]/
- route.ts
Directorysetup/
- route.ts
- auth.ts
- page.ts
- middleware.ts
- env.d.ts
- wrangler.toml
We've completed the backend steps for our application. Now, we need a way to sign in. First, let's install shadcn ↗:
Next, run the following to add a few components:
To make it easy, we've provided a basic sign-in interface for you below that you can copy into your app. You will likely want to customize this to fit your needs, but for now, this will let you sign in, see your account details, and update your user's name.
Replace the contents of page.ts
from within the app/
directory with the following:
Now, it's time to preview our app. Run the following to preview your application:
You should see our login form. But wait, we're not done yet. Remember to create your database tables by visiting /api/setup
. You should see Migration completed
. This means your database is ready to go.
Navigate back to your application's homepage. Enter your email and sign in (use the same email as your Resend account if you used the onboarding@resend.dev
address). You should receive an email in your inbox (check spam). Follow the link to sign in. If everything is configured correctly, you should now see a basic user profile letting your update your name and sign out.
Now let's deploy our application to production. From within the project's directory run:
This will build and deploy your application as a Worker. Note that you may need to select which account you want to deploy your Worker to. After your app is deployed, Wrangler should give you the URL on which it was deployed. It might look something like this: https://auth-js-d1-example.example.workers.dev
. Add your URL to your Worker using:
After the changes are deployed, you should now be able to access and try out your new application.
You have successfully created, configured, and deployed a fullstack Next.js application with authentication powered by Auth.js, Resend, and Cloudflare D1.
To build more with Workers, refer to Tutorials.
Find more information about the tools and services used in this tutorial at:
If you have any questions, need assistance, or would like to share your project, join the Cloudflare Developer community on Discord ↗ to connect with other developers and the Cloudflare team.