I’m working on an NFT project and running into a metadata URI problem during testing on the testnet.
My metadata files are stored on my server with the .json extension, like myproject.com/metadata/1.json, myproject.com/metadata/2.json, etc. But when I check the token URI that gets generated, it’s missing the file extension and just shows myproject.com/metadata/1 instead.
This means the metadata won’t load properly. Here’s my current base URI function:
function _baseURI() internal pure override returns (string memory) {
return "https://myproject.com/metadata/";
}
What’s the best way to modify this so it includes the .json extension? Do I need to override the tokenURI function instead or is there a simpler approach I’m missing?
To resolve the issue with your NFT metadata URI missing the file extension, you will need to override the tokenURI function rather than relying solely on _baseURI(). OpenZeppelin’s implementation merges the base URI with the token ID but does not automatically append the file extension. You can implement it as follows:
Additionally, ensure that you have imported @openzeppelin/contracts/utils/Strings.sol for the toString() function. I faced a similar challenge during my NFT deployment, and this solution has been effective.
Oh interesting! You’re hitting the same wall most of us hit when we first dive into NFT contracts
The others already nailed the technical solution with overriding tokenURI, but I’m curious - why’d you go with server-hosted metadata instead of IPFS? Planning to keep it centralized or just testing?
Also, what happens if someone queries a token ID that doesn’t exist yet? I noticed Ava61 included the _exists check which is pretty important. Without it you’ll get broken links floating around.
Btw, are you using the standard OpenZeppelin ERC721 contract as your base? Some custom implementations handle URI concatenation differently and you might need to adjust the approach depending on what you’re inheriting from.
Once you get this sorted, test it thoroughly on testnet - mint a few tokens and check the metadata loads properly in OpenSea testnets or wherever you’re planning to list. Nothing worse than discovering metadata issues after mainnet deployment!
yea, you gotta override tokenURI for this. just use return string(abi.encodePacked(_baseURI(), tokenId.toString(), ".json")). the base URI ain’t gonna add the extension for ya - you’ll have to stitch it together in the tokenURI override.