I'm building a trading card game gallery from JSON returned by an endpoint. Each card has a set number and card number, and the app builds image URLs such as `images/cards/sets/set-number/card-number.webp` before creating and appending the gallery elements.
This works well until the artwork for an existing card changes. Because the image URL stays the same, browsers may continue showing the cached version. The rest of the site is built with Vite, so I'm wondering whether Vite can bundle or fingerprint these dynamically loaded images too.
I'd rather not import every image manually or maintain a separate list of imports that has to be updated whenever the card data or artwork changes. Should I use Vite in some way for this, or is there a better approach for cache invalidation?
3 Answers
The simplest alternative is to rename the image whenever its artwork changes, or include a version token in the card data or query string. If you control the server, suitable cache headers can help too, but the key requirement is that the browser receives a different URL when the file content changes. There’s no need to import every dynamically requested image into Vite.
You don’t need to maintain the database and a JavaScript import list separately. Keep the JSON as the source of truth, then optionally run a build script that scans the image directory and creates a manifest mapping each card to a hashed filename or URL. The gallery can load that manifest and resolve the set and card numbers at runtime. When an image changes, its content hash changes on the next build, producing a new URL and avoiding stale browser caches.
This is mainly a cache-busting issue, not a bundling issue. Vite fingerprints assets that are imported as part of the build, but it cannot automatically process URLs assembled from JSON at runtime. Keep the images as public or otherwise server-served files and append a version to the URL when the artwork changes, such as `card.webp?v=2`. A `last_updated` value in the card JSON is a good way to generate that version without hardcoding it.

Using a `last_updated` field sounds ideal. It also clears up my misunderstanding about what Vite actually handles.