Skip to Content

TCGPlayer Images as Primary Source

Date2026-03-24
StatusAccepted
Decision Makers@benjaminW78

Context and Problem Statement

Two image sources are available for SWU cards:

  1. SWU API — Provides art crops at approximately 418x300 pixels. These are cropped card artwork, not full card renders (no border, no text frame).
  2. TCGPlayer (via TCGCSV) — Provides full card renders at 1000x1000 pixels. These show the complete card face including border, text, and artwork.

We need to decide which source to use as the primary image for product cards in the system.

Decision Drivers

  • Full card renders are more useful for inventory management and marketplace listings than art crops
  • TCGPlayer images are higher resolution (1000x1000 vs. 418x300)
  • Users expect to see the card as it appears in-hand, not just the artwork
  • The SWU API art crops are still valuable as a fallback when TCGPlayer images are unavailable (e.g., very new releases)
  • Other importers (Pokemon, One Piece, Pokemon Japan) already use TCGPlayer images as their primary source via the same toTcgCsvHighResImage() utility

Considered Options

  1. TCGPlayer primary, SWU API fallback: Use TCGPlayer images when available, fall back to SWU API art
  2. SWU API primary: Use the official API art crops as the primary image
  3. Both stored separately: Store both images and let the frontend decide which to display

Decision Outcome

Chosen option: TCGPlayer primary, SWU API fallback, because TCGPlayer provides higher-resolution full card renders, and this is consistent with how other game importers handle images.

Implementation

// Image: TCGPlayer high-res primary, SWU API art as fallback const tcgImageUrl = hasValidTcgCsvImage(product) ? toTcgCsvHighResImage(product.imageUrl) : null const apiImageUrl = apiMatch?.image?.front ?? null const imageSource = tcgImageUrl ?? apiImageUrl const imageExt = tcgImageUrl ? "jpg" : (apiImageUrl ? "png" : "jpg")

The toTcgCsvHighResImage() utility transforms the TCGCSV thumbnail URL into a high-resolution URL by replacing the _200w.jpg suffix with _in_1000x1000.jpg. This is the same utility used by the Pokemon, One Piece, and Pokemon Japan importers.

hasValidTcgCsvImage() checks that the TCGCSV product has a non-null, non-placeholder image URL before attempting the transformation.

Image resolution comparison

SourceResolutionContentFormat
TCGPlayer (TCGCSV)1000x1000Full card render (border, text, artwork)JPEG
SWU API~418x300Art crop (artwork only, no border/text)PNG

Impacted Files

FileKey SymbolsRole
packages/games/game-importer/src/star-wars-unlimited-importer.tsgetCards()Uses toTcgCsvHighResImage() for primary image, SWU API image.front as fallback
packages/games/game-importer/src/lib/tcg-csv/tcg-csv-image.tstoTcgCsvHighResImage(), hasValidTcgCsvImage()Shared utility for transforming TCGCSV thumbnail URLs to high-res URLs

Consequences

Positive

  • Higher-quality images (1000x1000 full card renders vs. 418x300 art crops)
  • Consistent with other game importers — same utility, same pattern
  • Users see the card as it appears physically, including borders and text
  • SWU API art is still available as a fallback for products that lack TCGPlayer images

Negative

  • TCGPlayer images may lag behind new releases — very new cards may not have images on TCGCSV yet, requiring the SWU API fallback
  • File extension differs between sources (JPEG for TCGPlayer, PNG for SWU API), which is tracked in imageExt for correct storage
Last updated on