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.
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
- Create a new page file,
pages/protected.jsx
, with the following content:
function Protected() {
return (
<div>
<h3>Protected content</h3>
</div>
);
}
export default Protected;
- 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 amessage
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.
- 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 usingMoralis.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;
- Visit the
http://localhost:3000/protected
page to test the NFT gated functionality. (http://localhost:3000/signin
for authentication.)