{"id":"ERC-4906","name":"NFT Metadata Update Extension","status":"Final","chain":"both","category":{"id":"nft","name":"NFT Capabilities","description":"What NFTs can do beyond basic ownership"},"journeyStages":[{"id":"asset-display","name":"Asset Discovery & Display","description":"Seeing tokens, NFTs, and balances"}],"uxImpact":"Standardized metadata update events — platforms know when to refresh NFT images/attributes. Design implications: implement real-time metadata refresh on update events, show 'Updated' indicators, handle batch metadata updates efficiently, display metadata version/history if tracked. Design decisions: how quickly to refresh after events, caching strategies, whether to notify users of updates to owned tokens, handling frequent updates without UI flicker.","hasDetailedContent":true,"content":{"id":"ERC-4906","sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-4906","type":"official-spec"}],"lastReviewed":"2026-05-25","lastUpdated":"2026-05-25","summary":"Standardized metadata update events — platforms know when to refresh NFT images/attributes.","designerTakeaways":["You can subscribe to 4906 events and refetch metadata automatically on update.","Your gallery can show subtle Updated chip after refresh completes.","You can debounce batch metadata updates to avoid image flicker during mass changes."],"applicability":{"whenToUse":["NFT metadata changes post-mint (reveals, evolving art).","Collection uses ERC-4906 update events.","Marketplaces must show fresh images."],"whenToAvoid":["Immutable metadata frozen at mint.","No event subscription infrastructure.","Updates so frequent UI cannot stabilize."]},"prototypeFirst":[{"screen":"Reveal moment refresh","why":"Pre-reveal to post-reveal is highest-stakes update.","covers":["Placeholder","Updating","Revealed"],"include":["Skeleton art","Refreshing spinner","New image fade-in"]},{"screen":"Updated badge on owned item","why":"Owners should know their NFT changed.","covers":["First view after update","Dismissed badge"],"include":["Updated chip","View changes link","Optional history"]},{"screen":"Batch metadata update","why":"Whole collection updates at once.","covers":["Batch event","Progress refresh"],"include":["Refreshing collection banner","Count updated","Done state"]},{"screen":"Stale cache fallback","why":"When refetch fails show honest state.","covers":["Fetch failed","Retry"],"include":["Could not refresh","Retry button","Last updated timestamp"]}],"mentalModel":[{"label":"Static metadata","description":"Old world — image never changes unless off-chain hack."},{"label":"Update event","description":"On-chain signal that tokenURI or attributes changed."},{"label":"Refetch","description":"App pulls new JSON and image after event."},{"label":"Reveal","description":"Special case of update — placeholder to final art."},{"label":"Batch update","description":"Many tokens updated — refresh without N separate spinners."}],"statesToDesign":[{"state":"Current metadata displayed","trigger":"Cache valid.","userNeed":"See accurate art.","designResponse":"Normal card display."},{"state":"Update detected — refreshing","trigger":"4906 event received.","userNeed":"Know image may change.","designResponse":"Subtle spinner overlay; keep old until new loads."},{"state":"Refresh complete","trigger":"New metadata fetched.","userNeed":"Notice change if owned.","designResponse":"Fade to new image; Updated badge optional."},{"state":"Batch collection refresh","trigger":"BatchMetadataUpdate.","userNeed":"Not see 1000 flickers.","designResponse":"Collection-level banner; debounced grid refresh."},{"state":"Refetch failed","trigger":"Gateway timeout.","userNeed":"Trust or retry.","designResponse":"Stale indicator with Retry refresh."}],"designDecisions":[{"question":"Notify owner on metadata update?","recommendation":"Optional push for owned tokens; silent for listings.","rationale":"Owners care; browsers do not need spam."},{"question":"Crossfade or hard swap?","recommendation":"Crossfade on reveal; instant on minor trait fix.","rationale":"Reveal is ceremonial; typo fix should be invisible."},{"question":"Cache TTL when no events?","recommendation":"Long cache with manual pull-to-refresh.","rationale":"4906 makes events primary refresh trigger."}],"problemsSolved":[{"problem":"Stale NFT images after reveal","oldWay":"Cache shows placeholder forever","newWay":"Event-driven refetch on MetadataUpdate","impact":"critical"},{"problem":"Platforms poll constantly","oldWay":"Wasteful polling every N seconds","newWay":"Update only on 4906 events","impact":"medium"},{"problem":"Users unaware metadata changed","oldWay":"Silent swap confuses owners","newWay":"Updated badge after refresh","impact":"medium"}],"uxPatterns":[{"name":"Event-Driven Refresh","description":"Auto-refetch on ERC-4906 metadata events.","mockup":"concept/nft-gallery","components":["EventListener","RefreshOverlay","UpdatedBadge"],"userFlow":["Event fires","Refetch starts","New art loads","Badge shows"]},{"name":"Reveal Transition","description":"Placeholder to final art crossfade.","mockup":"concept/nft-gallery","components":["PlaceholderArt","Crossfade","RevealBanner"],"userFlow":["Pre-reveal","Event received","Crossfade","Revealed state"]}],"seenInTheWild":[{"app":"OpenSea","url":"https://opensea.io/","note":"Refresh metadata button and reveal handling."},{"app":"Art Blocks","url":"https://www.artblocks.io/","note":"Generative reveal moments depend on metadata updates."},{"app":"Zora","url":"https://zora.co/","note":"Creator metadata updates on minted works."}],"antiPatterns":[{"pattern":"Never refetching after mint cache","why":"Permanent stale images post-reveal","instead":"Subscribe to 4906 and refetch","severity":"critical"},{"pattern":"Full grid flicker on batch update","why":"Epilepsy and distrust","instead":"Debounced batch refresh with banner","severity":"high"},{"pattern":"Hard swap without loading state","why":"Jarring image jump","instead":"Crossfade or skeleton during fetch","severity":"medium"}],"vocabulary":[{"use":"Artwork updated","avoid":"MetadataUpdate event emitted","why":"User-visible outcome."},{"use":"Refreshing","avoid":"Refetching tokenURI","why":"Loading state language."},{"use":"Reveal","avoid":"Batch metadata transition","why":"Collectible culture term."}],"onMonad":[{"aspect":"Update latency","ethereum":"Reveal wait feels long","monad":"Fast events enable snappier reveal UX","designImplication":"Tighter reveal animation timing on Monad."},{"aspect":"Batch updates","ethereum":"Mass refresh stresses gateways","monad":"High throughput collections need same debounce","designImplication":"Batch debounce still required on Monad."}],"technicalNotes":"ERC-4906 events are the refresh trigger; debounce BatchMetadataUpdate for grid stability.","relatedStandards":[{"id":"ERC-721","relationship":"Metadata update extension"},{"id":"ERC-5773","relationship":"Multi-asset tokens may update per asset"}]},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-4906","type":"official-spec"},{"label":"Discussion","url":"https://ethereum-magicians.org/search?q=ERC-4906","type":"discussion"},{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-4906","type":"official-spec"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-4906","markdown":"https://www.eipsfordesigners.com/standards/ERC-4906/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-4906/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-4906","official":"https://eips.ethereum.org/EIPS/erc-4906","discussion":"https://ethereum-magicians.org/search?q=ERC-4906"},"freshness":{"lastReviewed":"2026-05-25","lastUpdated":"2026-05-25"}}