Skip to main content

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: https://github.com/MoralisWeb3/demo-apps/tree/main/nextjs_moralis_nft_gating.

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