Building an NFT dApp: how to visualize an NFT (no shortcuts)

Jeffer1981
3 min readJan 6, 2023

NFTs have a lot of potential use cases, like e.g. games and identification. One thing you will always need to do when you build an app that makes use of NFTs, is visualizing them.

There are a number of javascript libraries out there that offer almost off the shelf functions to display NFTs on your app, but you might run into their limitations later on, especially when trying to build more complex functionality.

So let’s check out how to display NFTs … without shortcuts.

Step 1: having an NFT contract and Metamask

In this article I’m assuming you have an ERC721 deployed to an EVM enabled blockchain like Ethereum or Polygon. I’m also assuming you have Metamask installed as Metamask will be used as our gateway to the blockchain.

One of the key characteristics of using ERC721 is that the following function is implemented:

function tokenURI(uint256 tokenId) public view virtual override(ERC721) returns (string memory)

Calling tokenURI with a specified tokenId (the number of the NFT) will return you that NFTs metadata.

Step 2: get an NFTs metadata

So basically we need to call the tokenURI function from our frontend. This can be done by using Metamask and the ethers.js javascript library.

The advantage of using Metamask, or rather one of the advantages, is that you can also use it as a user identification platform.

To connect to a smart contract you need the following:

The contract address and its ABI

const NFTcontract="INSERT CONTRACT ADDRESS";
const myabi=[{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "tokenURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
} ];

The NFTcontract is just the address, the ABI is the contract interface definition. You can easily get it through e.g. remix.

Establishing a link to the contract with Metamask

const {ethers} = require('ethers');
var provider;
var MyContract;

//Metamask injects the ethereum object in window
const accounts = await window.ethereum.send("eth_requestAccounts")
//Get the current active address
const address = accounts.result[0];
//Link to the blockchain and the chosen address
provider = new ethers.providers.Web3Provider(window.ethereum);
MyContract = new ethers.Contract(NFTcontract, myabi, provider);

Note that the blockchain to which you try to connect, is determined by the active blockchain in Metamask. E.g. if your Metamask is connected to Goerli testnet, this setup will look for the contract on the Goerli testnet.

Request the metadata for an NFT

var myNFT;
myNFT = await MyContract.tokenURI(1);

This will fetch the metadata for the first NFT in the contract. The data returned will look like this:

data:application/json;base64,eyJuYW1lIjoiWW9zaGkiLCAiZGVzY3JpcHRpb24iOiJTdHJlZXRmaWdodGVycyEiLCJpbWFnZSI6ICJodHRwczovL2dhdGV3YXkucGluYXRhLmNsb3VkL2lwZnMvUW1RTk5NVHUzTlNqMVl5WEJGWmozR2dNNGk0N3ZKc01RdWI3TFcyb1U5NlcxQSIsICJhdHRyaWJ1dGVzIjogW3sidHJhaXRfdHlwZSI6ICJTdHJlbmd0aCIsInZhbHVlIjoiMiJ9LHsidHJhaXRfdHlwZSI6ICJTdGFtaW5hIiwidmFsdWUiOiI1In0seyJ0cmFpdF90eXBlIjogIlRlY2huaXF1ZSIsInZhbHVlIjoiMiJ9LHsidHJhaXRfdHlwZSI6ICJUb3VnaG5lc3MiLCJ2YWx1ZSI6IjIifV19

Not really readable or usable, is it? So let’s transform it to a JSON.

after_ = myNFT.substring(myNFT.indexOf(',') + 1);
buff = new Buffer(after_, 'base64');

var myNFTjson = JSON.parse(buff.toString());

This will return a JSON file like this:

{"name":"Yoshi", "description":"Streetfighters!","image": "https://gateway.pinata.cloud/ipfs/QmQNNMTu3NSj1YyXBFZj3GgM4i47vJsMQub7LW2oU96W1A", "attributes": [{"trait_type": "Strength","value":"2"},{"trait_type": "Stamina","value":"5"},{"trait_type": "Technique","value":"2"},{"trait_type": "Toughness","value":"2"}]}

Ah, perfect! A nicely readable and usable JSON! An ERC721 contract needs to follow certain metadata standards (see here), giving you some standard and some optional info:

  • Name
  • Description
  • Link to the image
  • Attributes

Now you can use the info from the JSON in your front end rendering. E.g. using tailwindcss:

<img className="rounded-t-lg mx-auto max-w-xs object-scale-down h-20 w-20" src={myNFTjson.image} alt="" />
<div className="p-5">

<h5 className="mb-2 text-center text-xl font-bold tracking-tight text-gray-900 dark:text-white">{myNFTjson.name}</h5>

</div>

This will result in something like this:

Conclusion

I hoped you enjoyed this short walkthrough. Visualing an NFT in your front end is the first step in building your dApp. Now you can expand the front end to e.g. an NFT marketplace, an NFT game,…

Let me know in the comments if you have additional questions or remarks!

--

--

Jeffer1981

Project Manager for ERP software | Tech enthousiast in python, AI | Loves sports and martial arts | Living in Belgium