Skip to main content
Version: 2.0

Token Gating Website (NextJS)

Introduction

This tutorial shows you how to create a NextJS dapp containing NFT gated functionality. We will create a protected page that's only accessible to users who authenticate and own at least one NFT from the specified NFT collection.

You can find the repository with the final code here.

If User Fulfills Requirements - This is the Landing Page

Before Starting

You can start this tutorial if you already have a NextJS dapp with Web3 authorization using next-auth. (Please check our NextJS Web3 Auth Tutorial.)

NFT Gated Page with getServerSideProps

  1. Create a new page file, pages/protected.jsx, with the following content:
function Protected() {
return (
<div>
<h3>Protected content</h3>
</div>
);
}
export default Protected;
  1. Add the getServerSideProps function for checking the user session. In case the user is not authenticated, we will redirect him to the /signin page. The message will be returned as a message prop and displayed on the client side:
import { getSession } from 'next-auth/react';
import Moralis from 'moralis';

function Protected({ message }) {
return (
<div>
<h3>Protected content</h3>
<p>{message}</p>
</div>
);
}

export async function getServerSideProps(context) {
const session = await getSession(context);

if (!session) {
return {
redirect: {
destination: '/signin',
permanent: false,
},
};
}


return {
props: {
message:
// if user has at least one NFT he will get congrats message
nftList.raw.total > 0 ? 'Nice! You have our NFT' : "Sorry, you don't have our NFT",
},
};
}
export default Protected;
info

The getServerSideProps only runs on the server side and never runs on the browser. When you request a page, getServerSideProps runs at request time, and this page will be pre-rendered with the returned props.

  1. Extend getServerSideProps . We will get the user wallet address from the user session object and check if the user has at least one specific NFT using Moralis.EvmApi:
import { getSession } from 'next-auth/react';
import Moralis from 'moralis';
import { EvmChain } from '@moralisweb3/common-evm-utils';

function Protected({ message, nftList }) {
return (
<div>
<h3>Protected content</h3>
<p>{message}</p>
<pre>{JSON.stringify(nftList, null, 2)}</pre>
</div>
);
}

export async function getServerSideProps(context) {
const session = await getSession(context);

if (!session) {
return {
redirect: {
destination: '/signin',
permanent: false,
},
};
}

if(!Moralis.Core.isStarted){
await Moralis.start({ apiKey: process.env.MORALIS_API_KEY });
}

const nftList = await Moralis.EvmApi.nft.getWalletNFTs({
chain: EvmChain.ETHEREUM,
address: session.user.address,
// replace "0x..." with your NFT token address
tokenAddresses: ["0x...", ],
});

return {
props: {
message:
// if user has at least one NFT he will get protected content
nftList.raw.total > 0 ? 'Nice! You have our NFT' : "Sorry, you don't have our NFT",
nftList: nftList.raw.result,
},
};
}
export default Protected;
  1. Visit the http://localhost:3000/protected page to test the NFT gated functionality. (http://localhost:3000/signin for authentication.)

Protected Page if User Does Not Fulfill Requirements

Protected Page When the User is Authenticated and Holds Specified NFT