Skip to main content

Next.js

Auth can be integrated into Next.js apps to enable wallet-based login. We'll go over the necessary setup below.

Installation

First, we need to install the @thirdweb-dev/auth package as follows:

npm install @thirdweb-dev/auth

Setup

We need to setup an admin private key used to secure our authentication. We can do this by creating a new .env.local file at the top level of the project and adding a private key to the file:

ADMIN_PRIVATE_KEY=your-private-key-here
Private Key Best Practices

It is not secure to store your private key in an environment variable.

Learn how to use a secret manager as we recommend here

Next, we'll want to setup the Auth endpoints to enable users to login and logout with their wallet.

We can setup all the necessary endpoints by creating a /pages/api/auth/[...thirdweb].js file:

import { ThirdwebAuth } from "@thirdweb-dev/auth/next";

export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({
// Using environment variables to secure your private key is a security vulnerability.
// Learn how to store your private key securely:
// https://portal.thirdweb.com/sdk/set-up-the-sdk/securing-your-private-key
privateKey: process.env.ADMIN_PRIVATE_KEY || "",
// Set this to your domain to prevent signature malleability attacks.
domain: "example.com",
});

// Export the handler to setup all your endpoints
export default ThirdwebAuthHandler();

Here, we configure Auth with the ThirdwebAuth function, passing in our private key and domain (used to prevent phishing attacks).

info

Importantly, the domain value here must match the domain that we use on the frontend when calling the login function.

This is all it takes to setup Auth for your Next.js backends. Now let's take a look at what you can do with this.

Usage

Once we setup Auth, we get two functions:

ThirdwebAuthHandler

The ThirdwebAuthHandler functions automatically handles all the necessary API endpoints needed for Auth, and should be exported from the /api/auth/[...thirdweb].js file.

More specifically, by exporting the handler we'll get the following API endpoints:

GET - /api/auth/login - Sets a JWT token for the user, allowing them to login with their wallet

GET - /api/auth/user - Gets the address of the user making a request (by accessing their JWT token)

GET - /api/auth/logout - Destroys the JWT token, logging out the user

getUser

The getUser function lets you get the user data of the authenticated user making a request to any other endpoint you may want to setup, including their address. You can use it in another endpoint as follows:

// Import getUser from wherever you created the config
import { getUser } from "/pages/api/auth/[...thirdweb]";

const handler = async (req, res) => {
// Get the authenticated user from the request
const user = await getUser(req);

// If the user is not authenticated, user will be null
if (!user) {
return res.status(401).json({
message: "Not authorized.",
});
}

// Otherwise, user.address will be set
return res.status(200).json({
address: user.address,
});
};

export default handler;

Frontend

Now that our backend setup, we can easily setup our React frontend (automatically included in Next.js) with a few hooks and buttons to enable login and logout.

First, we'll need to install the @thirdweb-dev/react package:

npm install @thirdweb-dev/react ethers

Now, in the _app.js file, we'll need to wrap our app with the ThirdwebProvider and provide some configuration for Auth:

import { ThirdwebProvider } from "@thirdweb-dev/react";

export default function MyApp({ Component, pageProps }) {
return (
<ThirdwebProvider
desiredChainId={1}
authConfig={{
// Set this to your domain to prevent signature malleability attacks.
domain: "example.com",
authUrl: "/api/auth",
}}
>
<Component {...pageProps} />
</ThirdwebProvider>
);
}

Here, we specify in the authConfig that our Auth backend is setup at the /api/auth URL, and that the domain we expect (which must match the domain we selected on the backend) is example.com (you would change this to your own domain).

Login Button

Now, we can use the ConnectWallet button to enable a simple login flow for our users:

import { ConnectWallet } from "@thirdweb-dev/react";

const Home = () => {
return <ConnectWallet />;
};

export default Home;

This button will allow user to connect their wallet via MetaMask, WalletConnect, and CoinbaseWallet, and then login to the backend with Auth.

Hooks

Alternatively, we can use the useLogin, useUser, and useLogout hooks to enable Auth functionality in the rest of our app.

For example, I can create the following component to allow users to login, logout, and view their address:

import {
useAddress,
useUser,
useLogin,
useLogout,
useMetamask,
} from "@thirdweb-dev/react";

const Home = () => {
const address = useAddress();
const connect = useMetamask();

const login = useLogin();
const logout = useLogout();
const { user } = useUser();

return (
<div>
{address ? (
<>
<button onClick={() => login()}>Login with Wallet</button>
<button onClick={logout}>Logout</button>
<pre>User: {JSON.stringify(user || null)}</pre>
</>
) : (
<button onClick={connect}>Connect Wallet</button>
)}
</div>
);
};

export default Home;

Here, we use the useLogin, useUser, and useLogout to enable a secure wallet based login flow for users on our frontend.