0
# NFT Components
1
2
Components for displaying and interacting with NFTs including automatic metadata loading, image display, and complete card layouts with pricing and actions.
3
4
## Capabilities
5
6
### NFTCard
7
8
Complete NFT card component providing image display, metadata rendering, price information, and interactive actions with support for different display styles.
9
10
```typescript { .api }
11
/**
12
* Complete NFT card component with image, metadata, price, and actions
13
* @param address - NFT contract address
14
* @param tokenId - NFT token ID
15
* @param type - Card display style: 'default' | 'pithy'
16
* @param price - Price display configuration
17
* @param like - Like functionality configuration
18
* @param showAction - Whether to show action button
19
* @param actionText - Custom action button text
20
* @param onActionClick - Action button callback
21
* @param errorRender - Custom error display function
22
* @param getNFTMetadata - Custom metadata fetcher function
23
*/
24
const NFTCard: React.FC<NFTCardProps>;
25
26
interface NFTCardProps {
27
address?: string;
28
tokenId?: number | bigint;
29
type?: 'default' | 'pithy';
30
price?: CryptoPriceProps;
31
like?: {
32
liked?: boolean;
33
likeCount?: number;
34
onLike?: (liked: boolean) => void;
35
};
36
showAction?: boolean;
37
actionText?: ReactNode;
38
onActionClick?: () => void;
39
errorRender?: (e: Error) => ReactNode;
40
getNFTMetadata?: UniversalWeb3ProviderInterface['getNFTMetadata'];
41
}
42
43
interface CryptoPriceProps {
44
value?: bigint;
45
symbol?: string;
46
decimals?: number;
47
chain?: Chain;
48
icon?: boolean | React.ReactNode;
49
fixed?: number;
50
format?: (value: bigint, decimals: number) => string;
51
}
52
```
53
54
**Usage Examples:**
55
56
```typescript
57
import { NFTCard } from "@ant-design/web3";
58
59
// Basic NFT card
60
<NFTCard
61
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
62
tokenId={1234}
63
/>
64
65
// NFT card with price and action
66
<NFTCard
67
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
68
tokenId={1234}
69
type="default"
70
price={{
71
value: BigInt("1000000000000000000"), // 1 ETH in wei
72
symbol: "ETH",
73
decimals: 18,
74
fixed: 3
75
}}
76
showAction
77
actionText="Buy Now"
78
onActionClick={() => {
79
console.log('NFT purchase clicked');
80
}}
81
/>
82
83
// Compact pithy style with like functionality
84
<NFTCard
85
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
86
tokenId={1234}
87
type="pithy"
88
like={{
89
liked: true,
90
likeCount: 42,
91
onLike: (liked) => {
92
console.log('NFT liked:', liked);
93
}
94
}}
95
/>
96
97
// Custom error handling
98
<NFTCard
99
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
100
tokenId={1234}
101
errorRender={(error) => (
102
<div style={{ padding: 20, color: 'red' }}>
103
Failed to load NFT: {error.message}
104
</div>
105
)}
106
/>
107
108
// Custom metadata fetcher
109
<NFTCard
110
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
111
tokenId={1234}
112
getNFTMetadata={async ({ address, tokenId }) => {
113
const response = await fetch(`/api/nft/${address}/${tokenId}`);
114
return response.json();
115
}}
116
/>
117
```
118
119
### NFTImage
120
121
Component for displaying NFT images with automatic metadata loading and fallback handling.
122
123
```typescript { .api }
124
/**
125
* Component for displaying NFT images with automatic metadata loading
126
* @param address - NFT contract address
127
* @param tokenId - NFT token ID
128
* @param getNFTMetadata - Metadata fetcher function
129
* Extends ImageProps from Ant Design for additional image properties
130
*/
131
const NFTImage: React.FC<NFTCardProps>;
132
133
interface NFTCardProps extends Omit<ImageProps, 'src'> {
134
address?: string;
135
tokenId?: bigint | number;
136
getNFTMetadata?: UniversalWeb3ProviderInterface['getNFTMetadata'];
137
}
138
139
interface ImageProps {
140
alt?: string;
141
width?: string | number;
142
height?: string | number;
143
placeholder?: React.ReactNode;
144
preview?: boolean | PreviewProps;
145
fallback?: string;
146
loading?: 'eager' | 'lazy';
147
onError?: (event: Event) => void;
148
onLoad?: (event: Event) => void;
149
}
150
```
151
152
**Usage Examples:**
153
154
```typescript
155
import { NFTImage } from "@ant-design/web3";
156
157
// Basic NFT image
158
<NFTImage
159
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
160
tokenId={1234}
161
/>
162
163
// NFT image with custom dimensions and preview
164
<NFTImage
165
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
166
tokenId={1234}
167
width={300}
168
height={300}
169
preview={true}
170
alt="Bored Ape #1234"
171
/>
172
173
// NFT image with fallback and loading states
174
<NFTImage
175
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
176
tokenId={1234}
177
fallback="https://via.placeholder.com/300x300?text=NFT+Not+Found"
178
placeholder={
179
<div style={{ width: 300, height: 300, background: '#f0f0f0' }}>
180
Loading NFT...
181
</div>
182
}
183
onError={(e) => console.log('Image load error:', e)}
184
onLoad={() => console.log('Image loaded successfully')}
185
/>
186
187
// Custom metadata fetcher
188
<NFTImage
189
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
190
tokenId={1234}
191
getNFTMetadata={async ({ address, tokenId }) => {
192
// Custom IPFS gateway or API endpoint
193
const response = await fetch(
194
`https://api.opensea.io/api/v1/asset/${address}/${tokenId}/`
195
);
196
const data = await response.json();
197
return {
198
name: data.name,
199
description: data.description,
200
image: data.image_url,
201
attributes: data.traits
202
};
203
}}
204
/>
205
```
206
207
## Types
208
209
### NFTMetadata Interface
210
211
```typescript { .api }
212
interface NFTMetadata {
213
name?: string;
214
description?: string;
215
image?: string;
216
dna?: string;
217
edition?: string | number;
218
date?: number;
219
attributes?: Array<{
220
trait_type?: string;
221
value?: string;
222
}>;
223
compiler?: string;
224
}
225
```
226
227
### UniversalWeb3ProviderInterface NFT Methods
228
229
```typescript { .api }
230
interface UniversalWeb3ProviderInterface {
231
getNFTMetadata?: (params: {
232
address: string;
233
tokenId?: bigint
234
}) => Promise<NFTMetadata>;
235
}
236
```
237
238
## Utility Functions
239
240
### Web3 Asset Loading
241
242
```typescript { .api }
243
/**
244
* Converts IPFS URLs to HTTP URLs for asset loading
245
* @param url - IPFS or HTTP URL
246
* @returns HTTP URL or undefined
247
*/
248
function getWeb3AssetUrl(url?: string): string | undefined;
249
250
/**
251
* Fetches and parses JSON from Web3 asset URLs
252
* @param url - Asset URL to fetch
253
* @returns Parsed JSON data
254
*/
255
async function requestWeb3Asset<T = any>(url: string): Promise<T>;
256
```
257
258
**Usage Examples:**
259
260
```typescript
261
import { getWeb3AssetUrl, requestWeb3Asset } from "@ant-design/web3";
262
263
// Convert IPFS URL to HTTP
264
const ipfsUrl = "ipfs://QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o";
265
const httpUrl = getWeb3AssetUrl(ipfsUrl);
266
// Returns: "https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o"
267
268
// Fetch NFT metadata
269
const metadata = await requestWeb3Asset<NFTMetadata>(
270
"https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o"
271
);
272
console.log('NFT Name:', metadata.name);
273
console.log('NFT Image:', metadata.image);
274
```
275
276
## Error Handling
277
278
NFT components include comprehensive error handling:
279
280
- **Loading States**: Components show loading indicators while fetching metadata
281
- **Error Boundaries**: Graceful fallback rendering when metadata loading fails
282
- **Custom Error Rendering**: `errorRender` prop allows custom error display
283
- **Fallback Images**: Support for fallback images when NFT image fails to load
284
- **Network Resilience**: Automatic retry logic for failed metadata requests
285
286
**Example Error Handling:**
287
288
```typescript
289
import { NFTCard } from "@ant-design/web3";
290
291
<NFTCard
292
address="0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
293
tokenId={1234}
294
errorRender={(error) => (
295
<div className="nft-error">
296
<h4>Unable to load NFT</h4>
297
<p>{error.message}</p>
298
<button onClick={() => window.location.reload()}>
299
Try Again
300
</button>
301
</div>
302
)}
303
/>
304
```