Catalogue & product data
Color Swatches & Visual Variant Selection
Generated from docs/plan/core/color-swatches-visual-variant-selection/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
Core feature enabling visual selection of product variants via color swatches, pattern images, or design previews. When a product has a Color or design attribute with images, the variant picker shows color boxes or product images instead of text dropdowns, letting customers see what they’re selecting before adding to cart. This is foundational for visual products (apparel, home, eyewear).
The problem
Customers can’t see what colors or designs they’re selecting; text dropdowns lose sales on visual products.
What it does
- Variant attribute images: when defining a variant option (e.g., ‘Red’ color), attach an image/swatch to that option
- Swatch rendering: show swatches as small colored boxes, pattern thumbnails, or product photos instead of text
- Swatch interaction: click/tap swatch to select variant option; shows variant image when selected
- Fallback to text: if no swatch image, show option as text (graceful degradation)
- Multiple swatch attributes: product with Color + Pattern both show swatches; selected combo shows variant image
- Swatch preview: hovering over swatch shows larger preview (desktop); tap shows preview (mobile)
- Accessibility: swatch has alt text and label; keyboard navigation works (arrow keys to switch swatches)
- Variant image sync: when swatch is selected, main product image changes to variant-specific image if available
- Out-of-stock indication: out-of-stock swatches show opacity/strikethrough, prevent selection
- Color hex codes (optional): for true color swatches, store hex code and render as CSS background-color
- CSV import: bulk-import variant images with product SKU and option value
- Admin swatch uploader: drag-drop or click to upload swatch images when editing variant options
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- 3D product views or AR try-ons — that’s advanced presentation; core provides 2D swatches only
- Automatic swatch generation (crop product image to show color) — merchant must upload/assign swatch manually
- Social proof on swatches (e.g., ‘5 people bought Red’) — that’s analytics plugin
- Variant availability with live inventory bar on swatch — swatch shows in/out of stock; inventory bar is presentation layer
Data model
Extend ProductVariant model to include swatch data: variant_option_metadata (for each option, store swatch_image_url, swatch_label, or color_hex). Example: {size: {value: ‘L’}, color: {value: ‘Red’, swatch_image: ‘/media/red-swatch.jpg’, color_hex: ‘#FF0000’}}. Can also extend ProductAttribute to allow option-level images: attribute_value (includes optional swatch_image_url, color_hex).
API
- GET /products/:id/variants — include swatch metadata (swatch_image_url, color_hex per variant option)
- PUT /products/:id/variants/:variant_id — accept swatch_image_url or color_hex for variant options
- POST /products/:id/attributes/:attr_id/values — accept swatch_image_url and color_hex when creating enum values
- PUT /attributes/:attr_id/values/:value_id — update swatch image or color_hex for attribute value
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Variant edit form gains swatch UI: (1) For each variant option (e.g., Color=Red), show image uploader/preview, (2) Optional color picker or hex input for true color swatches, (3) Auto-preview swatch in variant picker, (4) Bulk import swatch images (CSV with SKU, option_value, swatch_image_url). Attribute value editor (for enum attributes) includes swatch image/color uploader.
The seam — why this is core
Core owns variant swatch data schema and API. Storefront (Next.js) owns swatch rendering, preview interactions, and image swapping on selection. Core returns swatch URLs/colors; storefront decides visual presentation (size, shape, hover effects).
Core owns visual variant mapping in product schema and storefront rendering
Dependencies
- variant-management (core; swatches extend variant options)
- product-variant-selector (core; picker uses swatch data)
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- A variant option ‘Red’ with swatch_image=‘/red-swatch.jpg’ is returned by GET /products/:id/variants with swatch_image_url included.
- Clicking red swatch in picker selects Color=Red variant and updates main product image to variant.image if available.
- Color hex ‘#FF0000’ is stored and rendered by storefront as a colored box (CSS background-color).
- A swatch with in_stock=false is shown with opacity/strikethrough; click is disabled (variant cannot be selected).
- Keyboard navigation: arrow keys move focus between swatches; Enter selects.
- Screen reader announces: ‘Color swatch, Red, click to select’.
- Bulk import CSV with columns (SKU, option_value, swatch_image_url) uploads swatches for all variants in one go.
- Out-of-stock swatch is visually distinct (gray, strikethrough, or crossed-out); no click interaction.
Risks
If swatch images are not optimized, picker is slow to load (many images = slow initial render). If swatch colors (hex codes) don’t match actual variant colors, customers order wrong color. If variant images are not assigned, image-swap on swatch selection fails silently. If storefront rendering is inaccessible (no alt text, no keyboard support), screen readers and keyboard users cannot select variants.
Commercial context
| Suggested price | free (core) |
| Rival anchor | Color Swatch King, Globo, Easify (freemium apps; core feature of variants) |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.