Build a Gallery of Your NFTs using Next.js and Alchemy
Building an NFT gallery can be useful for several reasons. First, it allows you to showcase your NFT collection and make it easily accessible to potential buyers or interested individuals.
Second, it can increase the value of your NFTs by creating a unique and appealing display.
Third, creating an NFT gallery can be an exciting and creative way to engage with the NFT community and showcase your creativity and taste.
Finally, building an NFT gallery can be a valuable learning experience and allow you to develop your skills in web development, blockchain integration, and user experience design.
Alchemy is one of the most popular blockchain services that helps developers easily connect with blockchain networks like Ethereum and create applications that utilize the features of these networks.
We will use the Alchemy SDK to interact with the Ethereum blockchain, read data and metadata of NFTs. This SDK provides a simple and easy interface for developers to access the Ethereum network.
We will use the same Next.js infrastructure that we created and developed in the previous tutorial. To add the Alchemy SDK to the project, you can run the following command in your terminal.
pnpm add alchemy-sdk
This command will install the latest version of the Alchemy SDK for use in your Next.js project.
Next, we need to create a new instance of the SDK with our desired settings permanently. To do this, create a new file with the following title and content inside the utils
folder, with the name alchemy.ts
.
import { Alchemy, Network } from 'alchemy-sdk'
const alchemyApikey = process.env.ALCHEMY_API_KEY
const alchemy = new Alchemy({
apiKey: alchemyApikey,
network: Network.ETH_MAINNET,
})
export { alchemy }
Now we need a function that retrieves all NFTs belonging to a specific wallet address and returns an array of token metadata. Create a new file named nfts.ts
in the utils
folder with the following content.
import { alchemy } from './alchemy'
export type Nft = {
contractAddress: string
tokenId: string
name: string
type: string
tokenUri: string | null
imageUrl: string | null
updatedAt: string | null
}
const replaceIpfsUrl = (url: string) => {
if (url.startsWith('ipfs://')) {
return `https://cloudflare-ipfs.com/ipfs/${url.slice(7)}`
}
return url
}
export async function getNftsByAddress(address: string): Promise<Nft[]> {
// Retrieve NFTs owned by the wallet address
const nftsForOwner = await alchemy.nft.getNftsForOwner(address)
// Retrieve metadata for each NFT using Promise.all for concurrency
const nfts = await Promise.all(
nftsForOwner.ownedNfts.map(async (nft) => {
const metadata = await alchemy.nft.getNftMetadata(
nft.contract.address,
nft.tokenId,
{}, // Add empty options object to get all metadata, including custom attributes
)
const imageUrl = metadata.rawMetadata?.image ?? null
// Extract relevant metadata and return it as an Nft object
return {
contractAddress: nft.contract.address,
tokenId: nft.tokenId,
name: metadata.title,
type: metadata.tokenType,
tokenUri: metadata.tokenUri?.gateway ?? null,
imageUrl: imageUrl ? replaceIpfsUrl(imageUrl) : null,
updatedAt: metadata.timeLastUpdated ?? null,
}
}),
)
return nfts
}
This code provides a function called getNftsByAddress
that returns a list of information about NFTs belonging to a specific wallet address.
After writing the getNftsByAddress
function, to use it to build a gallery on a Next.js static site, you can use getStaticProps
to get the information related to NFTs and use it in your project.
Create a new file named gallery.tsx
inside the pages
directory. In this file, first import the getNftsByAddress
function and then use getStaticProps
to fetch the necessary data for the gallery.
import { GetStaticProps } from 'next'
import Image from 'next/image'
import Layout from '../components/layout'
import { getNftsByAddress, Nft } from '../utils/nfts'
type Props = {
nfts: Nft[]
}
const Gallery = ({ nfts }: Props) => {
return (
<>
<Layout title="Gallery">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3">
{nfts.map((nft) => (
<div key={`${nft.contractAddress}-${nft.tokenId}`}>
{nft.imageUrl && (
<div className="relative h-80">
<Image src={nft.imageUrl} alt={nft.name} fill />
</div>
)}
<div className="mt-2">{nft.name}</div>
</div>
))}
</div>
</Layout>
</>
)
}
export default Gallery
export const getStaticProps: GetStaticProps<Props> = async () => {
const walletAddress = process.env.WALLET_ADDRESS ?? ''
const nfts = await getNftsByAddress(walletAddress)
return {
props: {
nfts,
},
}
}
In the above code, we used getStaticProps
to fetch data related to NFTs and put them in props
. Then using this props
, we can create the desired gallery.
In this example, we used a div
with a grid
and 3-column layout to display images in different columns. Each image is in a separate div
and the name of the NFT along with its image is displayed.