How to store users with NextAuth (aka Auth) in Contentful

Published on February 28, 2023

How to store users with NextAuth (aka Auth) in Contentful

If you're a developer building a user interface for your application, then most likely you're using a JavaScript library like React.

A popular way to use it is through a React framework like Next.js, which has almost 100k stars in GitHub and used by more than 1M projects at the time of writing. It delivers a fast way to develop React apps while also being able to have backend parts in the codebase.

One of the first priorities when building a user-facing app will be authentication. NextAuth.js is a complete open-source authentication solution for Next.js applications (which will soon be renamed to Auth). 

NextAuth delivers a simple way to do authentication while being really flexible and letting you choose a lot of aspects of the implementation. In this post, we are going to connect NextAuth/Auth and Contentful to be able to store users directly in Contentful. 

Please note that your users need to have given consent to the usage and storage of all sensitive data (emails, phone numbers, etc) in your app or project. That isn’t covered by this tutorial. To avoid storing passwords, this tutorial will only consist of adding a social login that supports Google. It’s not too difficult to add login by password if that’s required.

To avoid confusion, we’ll refer to the authentication solution by its original name (NextAuth) and then update this post when the switch is finalized.

Why would you want to store user data in Contentful?

But first you might be thinking, why would you want to store user data in Contentful? And the answer is really simple — you get an amazing admin panel right from the start. 

You might be coding a website where the maintainers aren’t technical, for example, and they don’t want to touch the database to do admin tasks. So having a built-in user interface will save you from having to build it yourself.

All the code used in this post is available in contentful/next-auth-example and if you get stuck, don't hesitate to ask for help in our community Slack.

Requirements: To follow the example, you will need a Contentful account with a CMA token and a Next.js app where you want to add authentication.

1. Create the user store in Contentful

You’ll already have a space in your account as Contentful automatically assigns one to you when you sign up and create an account. If you prefer to do things in a separate space, just create a new one to use with this project.

To store the users, we are going to create a new ContentType. To keep things simple, we’re just going to have an email field, as it's the minimum NextAuth requires for social login, but you could add other info required on sign-up in your app.

email

2. Creating and configuring the Next.js project with NextAuth.js

Note: You can skip this step if you already have a project with NextAuth.

The repo will be configured to use TypeScript and if you want to use that you can go ahead but this tutorial doesn’t. All files created are JavaScript files and all code is JavaScript.

The easiest way to set up a new project is to use NextAuth's example project, so we will do that, and install some extra dependencies we need:

The next step is to configure your environment variables. NextAuth already gives you some in the example project, so we will use those and add the Contentful-specific ones.

For the NextAuth ones, just add to cp .env.local.example .env.local. Then add the following env vars to .env.local (with values of course):

Next, we will add our email form to our app. We will use the default login form that NextAuth gives us. Edit the [...nextauth].ts file in pages/api/auth to contain the following:

If you now navigate to /api/auth/signin you should see something very similar to this:

Sign in with Google

Something looks off, right? The Google icon doesn’t seem to be working because of a bug in NextAuth. But this shouldn’t be a problem as everything is functional and you can always change this page to load a different icon. 

Note: Use this if you are using the pages directory with Next.js 12

The next thing is to update your app to have the session in all pages. To do this, go to the pages/_app.ts file and update it to contain the following:

Note: If you used the NextAuth example this will already be done.

With this you will be able to use the useSession hook and access the session in any page without having to work directly with jwt.

Note: Use this if you are using Next.js 13 with the app directory

Right now, the app directory is in beta according to the Vercel docs, so this implementation is a bit hacky and doesn’t work great for server authentication, but you can keep track of this GitHub issue to be updated.

The most sensible way to implement this would be the following. Create an AuthContext.ts in your project with this code:

And then on the component you want to use the useSession hook you can wrap it with that context. An account page could look like this

3. Get the Google credentials for logging

As you might have seen we use GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET when setting up the Google provider. To get these values, you will need to go to Google Cloud Console and get an Oauth2.0 client id and client secret. 

Make sure that in authorized domains you add http://<yourUrl>/api/auth/callback/google and http://<yourUrl>/api/auth/callback/google as that’s where Google redirects after authentication.

Then, add these values to your .env.local file. It should look like this, with your own values

4. Creating the Contentful connection

For interacting with Contentful, we are going to use the contentful-management package. Create a contentful.js file in the root folder and add the following pieces of code:

Here we set some common variables and start the Contentful client. If you have anything different in your setup, just change the constants and it should work.

Next, we need a function to create the users in our user store. This function will take an email and a hashed password and store it.

The final step of our connection is to add a function to get users from Contentful. In my implementation, my getter function also signs up users in case of the user not existing, but you might want to change it. If your app is private, you could make it so it throws an error if it doesn't find the user.

We already have a way to connect our app with Contentful, but we need to tell NextAuth to use our functions. Go to the [...nextauth].js file again in pages/api/auth and inside the callbacks object add the following signIn function. It should look like this:

Note: You should import getOrCreateUser at the top of the file.

This will forward the user email to our previously created function.

4. Checking in the UI it all works

If you have used the NextAuth example, you should have a login/signup flow already working. You can check the flow is working by navigating to /api/auth/signin and doing a signup. You should get redirected to the index and see a new entry in your Contentful space.

If you were working in an existing project, the flow should be working. Now your NextAuth should be storing users in Contentful but you might need to change some more things than shown in the post.

Wrapping up

And there you have it. In this post, we explained how to add NextAuth (aka Auth) to your app and use Contentful as your user store/admin panel. 

You also have the option to add as many credentials providers as you want, here is the official list. We hope this saves you the trouble of creating a custom admin panel on your next app using NextAuth.

We hope you find this tutorial useful. If you have any questions, the best way to contact me would be on Twitter. Good luck and happy coding!

Subscribe for updates

Build better digital experiences with Contentful updates direct to your inbox.

Related articles

Guides

Dynamic static sites - Implementing an oxymoron

April 13, 2018

In this post we explore definitions of composability in relation to various fields of digital work, with a useful analogy to show composability in action.
Guides

Understanding composability: Definitions and explanations

August 29, 2023

Images are an effective means to express ideas or explain a concept.
Guides

Always look your best: WebP, source sets, and the Contentful Images API

September 20, 2022

Contentful Logo 2.5 Dark

Ready to start building?

Put everything you learned into action. Create and publish your content with Contentful — no credit card required.

Get started