@thorprovider/create-storefront 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -0
- package/bin/install.js +116 -0
- package/commands/sf-add-view.md +21 -0
- package/commands/sf-init.md +16 -0
- package/commands/sf-theme.md +15 -0
- package/commands/sf-view.md +20 -0
- package/package.json +40 -0
- package/recipes/archetype.schema.json +39 -0
- package/recipes/archetypes.json +148 -0
- package/recipes/recipe.schema.json +59 -0
- package/recipes/recipes.json +90 -0
- package/recipes/sections.json +46 -0
- package/recipes/validate.mjs +190 -0
- package/skills/building-storefronts/SKILL.md +178 -0
- package/skills/building-storefronts/references/frontend-integration.md +229 -0
- package/skills/json-render-core/SKILL.md +291 -0
- package/skills/json-render-next/SKILL.md +194 -0
- package/skills/json-render-react/SKILL.md +298 -0
- package/skills/json-render-remotion/SKILL.md +111 -0
- package/skills/json-render-shadcn/SKILL.md +159 -0
- package/skills/json-render-solid/SKILL.md +204 -0
- package/skills/nextjs-shadcn/SKILL.md +303 -0
- package/skills/nextjs-shadcn/references/architecture.md +499 -0
- package/skills/nextjs-shadcn/references/project-setup.md +127 -0
- package/skills/nextjs-shadcn/references/shadcn-platform.md +258 -0
- package/skills/nextjs-shadcn/references/sidebar.md +274 -0
- package/skills/nextjs-shadcn/references/styling.md +555 -0
- package/skills/sf-scaffold/SKILL.md +118 -0
- package/skills/sf-theme-gen/SKILL.md +44 -0
- package/skills/sf-view-gen/SKILL.md +94 -0
- package/skills/shadcn-component-discovery/SKILL.md +273 -0
- package/skills/shadcn-component-discovery/references/registries.md +226 -0
- package/skills/shadcn-theming/SKILL.md +104 -0
- package/skills/shadcn-theming/references/templates/theme-setup.md +109 -0
- package/skills/shadcn-theming/references/theming-guide.md +90 -0
- package/skills/storefront-best-practices/SKILL.md +421 -0
- package/skills/storefront-best-practices/reference/components/breadcrumbs.md +123 -0
- package/skills/storefront-best-practices/reference/components/cart-popup.md +189 -0
- package/skills/storefront-best-practices/reference/components/country-selector.md +298 -0
- package/skills/storefront-best-practices/reference/components/footer.md +112 -0
- package/skills/storefront-best-practices/reference/components/hero.md +241 -0
- package/skills/storefront-best-practices/reference/components/megamenu.md +239 -0
- package/skills/storefront-best-practices/reference/components/navbar.md +397 -0
- package/skills/storefront-best-practices/reference/components/popups.md +221 -0
- package/skills/storefront-best-practices/reference/components/product-card.md +125 -0
- package/skills/storefront-best-practices/reference/components/product-reviews.md +217 -0
- package/skills/storefront-best-practices/reference/components/product-slider.md +174 -0
- package/skills/storefront-best-practices/reference/components/search.md +101 -0
- package/skills/storefront-best-practices/reference/connecting-to-backend.md +391 -0
- package/skills/storefront-best-practices/reference/design.md +388 -0
- package/skills/storefront-best-practices/reference/features/promotions.md +307 -0
- package/skills/storefront-best-practices/reference/features/wishlist.md +230 -0
- package/skills/storefront-best-practices/reference/layouts/account.md +380 -0
- package/skills/storefront-best-practices/reference/layouts/cart.md +316 -0
- package/skills/storefront-best-practices/reference/layouts/checkout.md +486 -0
- package/skills/storefront-best-practices/reference/layouts/home-page.md +264 -0
- package/skills/storefront-best-practices/reference/layouts/order-confirmation.md +231 -0
- package/skills/storefront-best-practices/reference/layouts/product-details.md +527 -0
- package/skills/storefront-best-practices/reference/layouts/product-listing.md +520 -0
- package/skills/storefront-best-practices/reference/layouts/static-pages.md +356 -0
- package/skills/storefront-best-practices/reference/medusa.md +307 -0
- package/skills/storefront-best-practices/reference/mobile-responsiveness.md +183 -0
- package/skills/storefront-best-practices/reference/seo.md +195 -0
- package/templates/app/app/[[...slug]]/page.tsx +17 -0
- package/templates/app/app/[[...slug]]/renderer.tsx +10 -0
- package/templates/app/app/globals.css +101 -0
- package/templates/app/app/layout.tsx +35 -0
- package/templates/app/lib/__STOREFRONT__/catalog.ts +132 -0
- package/templates/app/lib/__STOREFRONT__/handlers.ts +33 -0
- package/templates/app/lib/__STOREFRONT__/registry.tsx +134 -0
- package/templates/app/lib/__STOREFRONT__/runtime.ts +25 -0
- package/templates/app/lib/__STOREFRONT__/spec/home.ts +62 -0
- package/templates/app/lib/__STOREFRONT__/spec/index.ts +59 -0
- package/templates/app/lib/__STOREFRONT__/spec/types.ts +14 -0
- package/templates/app/lib/__STOREFRONT__/state.ts +35 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
# Product Detail Page Layout
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [Overview](#overview)
|
|
6
|
+
- [Layout Structure](#layout-structure)
|
|
7
|
+
- [Price Display and Medusa Integration](#price-display-and-medusa-integration)
|
|
8
|
+
- [Variant Selection (Critical)](#variant-selection-critical)
|
|
9
|
+
- [Stock Availability](#stock-availability)
|
|
10
|
+
- [Add to Cart Behavior](#add-to-cart-behavior)
|
|
11
|
+
- [Product Details Organization](#product-details-organization)
|
|
12
|
+
- [Related Products Strategy](#related-products-strategy)
|
|
13
|
+
- [Trust Signals and Conversion](#trust-signals-and-conversion)
|
|
14
|
+
- [Mobile Optimization](#mobile-optimization)
|
|
15
|
+
- [Checklist](#checklist)
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
Most critical page for conversion. Customers make purchase decisions here based on product information, images, reviews, and trust signals.
|
|
20
|
+
|
|
21
|
+
### Key Requirements
|
|
22
|
+
|
|
23
|
+
- High-quality product images with zoom capability
|
|
24
|
+
- Clear price display (handle variant price changes)
|
|
25
|
+
- Variant selection (size, color, material)
|
|
26
|
+
- Stock availability indicators
|
|
27
|
+
- Prominent "Add to Cart" with proper feedback
|
|
28
|
+
- Product details (description, specifications)
|
|
29
|
+
- Customer reviews and ratings
|
|
30
|
+
- Related product recommendations
|
|
31
|
+
- Trust signals (shipping, returns, secure checkout)
|
|
32
|
+
- Mobile-optimized (60%+ traffic)
|
|
33
|
+
|
|
34
|
+
### Routing Pattern
|
|
35
|
+
|
|
36
|
+
**CRITICAL: Always use dynamic routes, NEVER static pages.**
|
|
37
|
+
|
|
38
|
+
Product detail pages must use dynamic routes that accept a parameter (handle, slug, or ID):
|
|
39
|
+
|
|
40
|
+
**Correct examples:**
|
|
41
|
+
- Next.js App Router: `app/products/[handle]/page.tsx`
|
|
42
|
+
- Next.js Pages Router: `pages/products/[handle].tsx`
|
|
43
|
+
- SvelteKit: `routes/products/[handle]/+page.svelte`
|
|
44
|
+
- TanStack Start: `routes/products/$handle.tsx`
|
|
45
|
+
- Remix: `routes/products.$handle.tsx`
|
|
46
|
+
|
|
47
|
+
**Wrong examples:**
|
|
48
|
+
- ❌ `pages/products/blue-shirt.tsx` (static file per product)
|
|
49
|
+
- ❌ `pages/products/red-shoes.tsx` (doesn't scale)
|
|
50
|
+
|
|
51
|
+
Fetch product data in the dynamic route based on the handle/ID parameter from the URL.
|
|
52
|
+
|
|
53
|
+
## Layout Structure
|
|
54
|
+
|
|
55
|
+
**Desktop (two-column):**
|
|
56
|
+
- Left: Product images (50-60% width)
|
|
57
|
+
- Right: Product info, variants, add to cart (40-50%)
|
|
58
|
+
- Below: Product details, reviews, related products (full-width)
|
|
59
|
+
|
|
60
|
+
**Mobile (stacked):**
|
|
61
|
+
- Images at top (full-width, swipeable)
|
|
62
|
+
- Product info below (title, price, rating)
|
|
63
|
+
- Variants and add to cart
|
|
64
|
+
- Accordion for product details
|
|
65
|
+
- Reviews section
|
|
66
|
+
- Related products
|
|
67
|
+
- Sticky "Add to Cart" bar at bottom
|
|
68
|
+
|
|
69
|
+
**Sticky sidebar option (desktop):**
|
|
70
|
+
- Product info column stays visible during scroll
|
|
71
|
+
- Add to cart always accessible
|
|
72
|
+
- Useful for long product descriptions
|
|
73
|
+
- Improves conversion
|
|
74
|
+
|
|
75
|
+
## Price Display
|
|
76
|
+
|
|
77
|
+
### Standard Price Display
|
|
78
|
+
|
|
79
|
+
**Current price:**
|
|
80
|
+
- Large, bold font (28-36px)
|
|
81
|
+
- Currency symbol included ($49.99)
|
|
82
|
+
- Primary color or black
|
|
83
|
+
|
|
84
|
+
**Sale pricing:**
|
|
85
|
+
- Original price with strikethrough: ~~$79.99~~ $49.99
|
|
86
|
+
- Sale price in red or brand color
|
|
87
|
+
- "Save X%" badge nearby
|
|
88
|
+
- Example: Save 37%
|
|
89
|
+
|
|
90
|
+
**Variant price changes:**
|
|
91
|
+
- **When no variant selected**: Show "From $X" where X is the minimum variant price across all variants
|
|
92
|
+
- **When variant selected**: Update price dynamically to show the exact variant price
|
|
93
|
+
- No page reload required
|
|
94
|
+
- Show price change clearly (highlight briefly on change)
|
|
95
|
+
- Example: Product with variants priced at $29.99, $34.99, $39.99 → Show "From $29.99" initially
|
|
96
|
+
|
|
97
|
+
### Medusa Pricing (CRITICAL)
|
|
98
|
+
|
|
99
|
+
**Important difference from Stripe:**
|
|
100
|
+
- Medusa stores prices as-is (e.g., 49.99)
|
|
101
|
+
- Display directly: If API returns 49.99, show $49.99
|
|
102
|
+
- **DON'T divide by 100** (unlike Stripe which stores in cents)
|
|
103
|
+
- Example: Medusa 49.99 → Display $49.99 (NOT $0.4999)
|
|
104
|
+
|
|
105
|
+
**Multi-currency (Medusa):**
|
|
106
|
+
- Medusa supports multi-region pricing
|
|
107
|
+
- Display price in user's region currency
|
|
108
|
+
- Fetch pricing from selected region
|
|
109
|
+
- Show currency code (usd, eur, etc.)
|
|
110
|
+
|
|
111
|
+
## Variant Selection (Critical)
|
|
112
|
+
|
|
113
|
+
This is a complex ecommerce-specific challenge. Variants affect price, stock, and images.
|
|
114
|
+
|
|
115
|
+
### Variant Complexity
|
|
116
|
+
|
|
117
|
+
**Key challenges:**
|
|
118
|
+
- Multiple variant types (size, color, material)
|
|
119
|
+
- Variant availability varies (some sizes out of stock)
|
|
120
|
+
- Prices may differ by variant
|
|
121
|
+
- Images change by color variant
|
|
122
|
+
- Stock levels per variant
|
|
123
|
+
- Combinations may not exist (size M + color Red might not exist)
|
|
124
|
+
|
|
125
|
+
**Fetch from backend:**
|
|
126
|
+
```typescript
|
|
127
|
+
// Get all variants for product
|
|
128
|
+
// Change this based on the backend integrated
|
|
129
|
+
const product = await fetch(`/products/${id}?fields=*variants`)
|
|
130
|
+
// Returns variants with: id, sku, options, calculated_price, inventory_quantity
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Variant Selection Patterns
|
|
134
|
+
|
|
135
|
+
**Use Button Group when:**
|
|
136
|
+
- 2-8 options per variant type
|
|
137
|
+
- Size selection (XS, S, M, L, XL)
|
|
138
|
+
- Simple color options (5-6 colors)
|
|
139
|
+
- Users need to see all options at once
|
|
140
|
+
|
|
141
|
+
**Benefits:**
|
|
142
|
+
- Visible options (no click to reveal)
|
|
143
|
+
- Faster selection
|
|
144
|
+
- Clear visual feedback
|
|
145
|
+
- Better UX
|
|
146
|
+
|
|
147
|
+
**Use Dropdown when:**
|
|
148
|
+
- 10+ options per variant type
|
|
149
|
+
- Material/style options with long names
|
|
150
|
+
- Space-constrained layouts
|
|
151
|
+
- Mobile optimization needed
|
|
152
|
+
|
|
153
|
+
**Benefits:**
|
|
154
|
+
- Saves space
|
|
155
|
+
- Works better for many options
|
|
156
|
+
- Mobile-friendly
|
|
157
|
+
|
|
158
|
+
**Use Visual Swatches when:**
|
|
159
|
+
- Color or pattern variations
|
|
160
|
+
- Material with visual differences
|
|
161
|
+
- Visual is key to decision
|
|
162
|
+
- Fashion, home decor, customizable products
|
|
163
|
+
|
|
164
|
+
**Implementation:**
|
|
165
|
+
- Circular/square swatches (40-48px)
|
|
166
|
+
- Border on selected
|
|
167
|
+
- Show product image in that color when selected
|
|
168
|
+
- Color name on hover
|
|
169
|
+
- Gray out unavailable colors
|
|
170
|
+
|
|
171
|
+
### Variant Selection Flow
|
|
172
|
+
|
|
173
|
+
**Critical sequence:**
|
|
174
|
+
1. User selects first variant type (e.g., Color: Blue)
|
|
175
|
+
2. **Update available options** for other variant types
|
|
176
|
+
3. Show only size options available for Blue color
|
|
177
|
+
4. Gray out/disable unavailable combinations
|
|
178
|
+
5. Update price if variant price differs
|
|
179
|
+
6. Update main product image to show selected variant
|
|
180
|
+
7. Update stock availability
|
|
181
|
+
8. Enable/disable "Add to Cart" based on availability
|
|
182
|
+
|
|
183
|
+
**Example: Two variants (Color + Size)**
|
|
184
|
+
```typescript
|
|
185
|
+
// When color selected
|
|
186
|
+
// Change this based on the backend integrated
|
|
187
|
+
onColorSelect(color) {
|
|
188
|
+
// Find selected variant
|
|
189
|
+
const selectededVariant = product.variants.find((variant) => variant.options?.every(
|
|
190
|
+
(optionValue) => optionValue.id === selectedOptions[optionValue.option_id!]
|
|
191
|
+
))
|
|
192
|
+
|
|
193
|
+
// Check if size is selected and update price
|
|
194
|
+
if (selectededVariant) {
|
|
195
|
+
const variant = findVariant(color, selectedSize)
|
|
196
|
+
updatePrice(variant.price)
|
|
197
|
+
updateStock(variant.inventory_quantity)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Validation and Error Handling
|
|
203
|
+
|
|
204
|
+
**Prevent adding without selection:**
|
|
205
|
+
- Disable "Add to Cart" until all required variants selected
|
|
206
|
+
- Or: Show error message "Please select a size"
|
|
207
|
+
- Highlight missing selection (red border around options)
|
|
208
|
+
- Scroll to variant selection on error
|
|
209
|
+
|
|
210
|
+
**Handle out of stock variants:**
|
|
211
|
+
- Gray out unavailable options
|
|
212
|
+
- "Out of stock" text on hover
|
|
213
|
+
- Don't allow selection of out of stock variants
|
|
214
|
+
- Suggest alternative variants if available
|
|
215
|
+
|
|
216
|
+
**Handle variant not found:**
|
|
217
|
+
- When combination doesn't exist (Size M + Color Red)
|
|
218
|
+
- Disable second option when first selected
|
|
219
|
+
- Show only valid combinations
|
|
220
|
+
- Or: Show "This combination is not available"
|
|
221
|
+
|
|
222
|
+
## Stock Availability
|
|
223
|
+
|
|
224
|
+
**Display patterns:**
|
|
225
|
+
|
|
226
|
+
**In stock:**
|
|
227
|
+
- Green indicator (✓ or dot)
|
|
228
|
+
- "In stock" or "Available"
|
|
229
|
+
- Quantity if low: "Only 3 left"
|
|
230
|
+
- Encourages urgency without being pushy
|
|
231
|
+
|
|
232
|
+
**Out of stock:**
|
|
233
|
+
- Red indicator (✗ or dot)
|
|
234
|
+
- "Out of stock" message
|
|
235
|
+
- Disable "Add to Cart" button (grayed out)
|
|
236
|
+
- Offer "Notify me when available"
|
|
237
|
+
- Email capture for restock notifications (if supported by backend)
|
|
238
|
+
|
|
239
|
+
**Low stock warning:**
|
|
240
|
+
- "Only X left in stock"
|
|
241
|
+
- Shows scarcity (increases urgency)
|
|
242
|
+
- Typically show when <= 5 items
|
|
243
|
+
- Orange/yellow color
|
|
244
|
+
|
|
245
|
+
**Pre-order:**
|
|
246
|
+
- "Pre-order now" status
|
|
247
|
+
- Expected availability date: "Ships on [Date]"
|
|
248
|
+
- Different button text: "Pre-order" instead of "Add to Cart"
|
|
249
|
+
- Charge now or later (specify)
|
|
250
|
+
|
|
251
|
+
**Backend integration:**
|
|
252
|
+
```typescript
|
|
253
|
+
// Fetch stock for selected variant
|
|
254
|
+
const stock = selectedVariant.inventory_quantity
|
|
255
|
+
|
|
256
|
+
if (stock === 0) {
|
|
257
|
+
showOutOfStock()
|
|
258
|
+
} else if (stock <= 5) {
|
|
259
|
+
showLowStock(stock) // "Only 3 left"
|
|
260
|
+
} else {
|
|
261
|
+
showInStock()
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Add to Cart Behavior
|
|
266
|
+
|
|
267
|
+
**Button states:**
|
|
268
|
+
- Default: Enabled (after variant selected)
|
|
269
|
+
- Hover: Slight color change or scale
|
|
270
|
+
- Loading: Spinner inside button (during API call)
|
|
271
|
+
- Success: Checkmark briefly, then revert
|
|
272
|
+
- Disabled: Grayed out (no variant or out of stock)
|
|
273
|
+
|
|
274
|
+
**Click behavior (Critical):**
|
|
275
|
+
1. Show loading state (disable button, show spinner)
|
|
276
|
+
2. Call API to add item to cart (backend)
|
|
277
|
+
3. **Optimistic UI**: Update cart count immediately (before API response)
|
|
278
|
+
4. Show success feedback (toast, checkmark, or cart popup)
|
|
279
|
+
5. Update cart count in navbar header
|
|
280
|
+
6. **DON'T navigate away** - stay on product page
|
|
281
|
+
7. Handle errors: restore count if API fails
|
|
282
|
+
|
|
283
|
+
**Success feedback options:**
|
|
284
|
+
- Toast notification: "Added to cart" (top-right)
|
|
285
|
+
- Cart popup: Show mini cart with items (see cart-popup.md)
|
|
286
|
+
- Checkmark in button briefly, then revert
|
|
287
|
+
- All three combined (checkmark + toast or cart popup)
|
|
288
|
+
|
|
289
|
+
**Error handling:**
|
|
290
|
+
```typescript
|
|
291
|
+
async function addToCart(variantId, quantity) {
|
|
292
|
+
try {
|
|
293
|
+
// Optimistic update
|
|
294
|
+
updateCartCountUI(+quantity)
|
|
295
|
+
|
|
296
|
+
// API call
|
|
297
|
+
// Change this based on the backend integrated
|
|
298
|
+
await fetch(`/store/carts/${cartId}/line-items`, {
|
|
299
|
+
method: 'POST',
|
|
300
|
+
body: JSON.stringify({ variant_id: variantId, quantity })
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
// Success feedback
|
|
304
|
+
showToast('Added to cart')
|
|
305
|
+
showCartPopup() // Optional
|
|
306
|
+
} catch (error) {
|
|
307
|
+
// Revert optimistic update
|
|
308
|
+
updateCartCountUI(-quantity)
|
|
309
|
+
|
|
310
|
+
// Show error
|
|
311
|
+
if (error.message === 'OUT_OF_STOCK') {
|
|
312
|
+
showError('Sorry, this item is now out of stock')
|
|
313
|
+
updateStockStatus('out_of_stock')
|
|
314
|
+
} else {
|
|
315
|
+
showError('Failed to add to cart. Please try again.')
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Buy Now button (optional):**
|
|
322
|
+
- Skip cart, go directly to checkout
|
|
323
|
+
- Useful for: high-value items, single-item stores, decisive customers
|
|
324
|
+
- Secondary button below "Add to Cart"
|
|
325
|
+
- Text: "Buy Now" or "Buy It Now"
|
|
326
|
+
- Add to cart + redirect to checkout in one action
|
|
327
|
+
|
|
328
|
+
## Product Details Organization
|
|
329
|
+
|
|
330
|
+
### Decision: Tabs vs Accordion
|
|
331
|
+
|
|
332
|
+
**Use Tabs (desktop) when:**
|
|
333
|
+
- 3-5 distinct sections
|
|
334
|
+
- Each section has substantial content
|
|
335
|
+
- Users may want to compare sections
|
|
336
|
+
- Desktop has screen space
|
|
337
|
+
- Examples: Description, Specifications, Shipping, Reviews
|
|
338
|
+
|
|
339
|
+
**Use Accordion (mobile) always:**
|
|
340
|
+
- Saves vertical space
|
|
341
|
+
- Users expand what they need
|
|
342
|
+
- Standard mobile pattern
|
|
343
|
+
- Collapses after reading
|
|
344
|
+
|
|
345
|
+
**Hybrid approach (recommended):**
|
|
346
|
+
- Tabs on desktop (horizontal navigation)
|
|
347
|
+
- Accordion on mobile (vertical expansion)
|
|
348
|
+
- Same content, different presentation
|
|
349
|
+
- Best of both worlds
|
|
350
|
+
|
|
351
|
+
### Common Sections
|
|
352
|
+
|
|
353
|
+
**Description:**
|
|
354
|
+
- Product overview (2-4 paragraphs)
|
|
355
|
+
- Key features (bullet points)
|
|
356
|
+
- Use cases
|
|
357
|
+
- Materials and craftsmanship
|
|
358
|
+
|
|
359
|
+
**Specifications:**
|
|
360
|
+
- Technical details (table format)
|
|
361
|
+
- Dimensions, weight, materials
|
|
362
|
+
- Care instructions
|
|
363
|
+
- Compatibility information
|
|
364
|
+
|
|
365
|
+
**Shipping & Returns:**
|
|
366
|
+
- Shipping options and costs
|
|
367
|
+
- Delivery timeframes
|
|
368
|
+
- Return policy (30 days, 60 days)
|
|
369
|
+
- Return process
|
|
370
|
+
- Link to full policy page
|
|
371
|
+
|
|
372
|
+
**Reviews:**
|
|
373
|
+
- Embedded in tab/accordion
|
|
374
|
+
- Or: Separate section below
|
|
375
|
+
- Filter by rating, sort by date
|
|
376
|
+
- Review submission form
|
|
377
|
+
|
|
378
|
+
## Related Products Strategy
|
|
379
|
+
|
|
380
|
+
**Types of recommendations:**
|
|
381
|
+
|
|
382
|
+
**"You May Also Like" (Similar products):**
|
|
383
|
+
- Same category, similar price point
|
|
384
|
+
- Algorithm: category match + price range
|
|
385
|
+
- Goal: Show alternatives if unsure about current product
|
|
386
|
+
|
|
387
|
+
**"Frequently Bought Together" (Complementary):**
|
|
388
|
+
- Products commonly purchased together
|
|
389
|
+
- Algorithm: order history analysis
|
|
390
|
+
- Goal: Increase average order value
|
|
391
|
+
- Example: Phone + Case + Screen Protector
|
|
392
|
+
- Show bundle discount if available
|
|
393
|
+
|
|
394
|
+
**"Recently Viewed" (Browsing history):**
|
|
395
|
+
- User's browsing history (session or logged-in)
|
|
396
|
+
- Helps users return to products they liked
|
|
397
|
+
- Goal: Reduce decision paralysis
|
|
398
|
+
|
|
399
|
+
**"Customers Also Viewed":**
|
|
400
|
+
- Products viewed by others who viewed this
|
|
401
|
+
- Algorithm: co-viewing patterns
|
|
402
|
+
- Goal: Discovery and alternatives
|
|
403
|
+
|
|
404
|
+
### Display Pattern
|
|
405
|
+
|
|
406
|
+
**Product slider:**
|
|
407
|
+
- 4-6 products visible (desktop)
|
|
408
|
+
- 2-3 visible (mobile)
|
|
409
|
+
- Horizontal scrolling (swipe on mobile)
|
|
410
|
+
- Product cards: image, title, price, rating
|
|
411
|
+
- Optional: Quick "Add to Cart" on hover
|
|
412
|
+
|
|
413
|
+
**Placement:**
|
|
414
|
+
- Below product details and reviews
|
|
415
|
+
- Above footer
|
|
416
|
+
- Full-width section
|
|
417
|
+
- Clear heading for each type
|
|
418
|
+
|
|
419
|
+
**Backend integration:**
|
|
420
|
+
```typescript
|
|
421
|
+
// Fetch recommendations
|
|
422
|
+
// Change this based on the backend integrated
|
|
423
|
+
const recommendations = await fetch(`/products/${id}/recommendations`)
|
|
424
|
+
// Returns: similar, bought_together, recently_viewed
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Trust Signals and Conversion
|
|
428
|
+
|
|
429
|
+
**Essential trust signals:**
|
|
430
|
+
|
|
431
|
+
**Near Add to Cart:**
|
|
432
|
+
- Free shipping badge (if applicable)
|
|
433
|
+
- Free returns icon + text
|
|
434
|
+
- Secure checkout icon
|
|
435
|
+
- Money-back guarantee
|
|
436
|
+
- Warranty information (if applicable)
|
|
437
|
+
|
|
438
|
+
**Below product title:**
|
|
439
|
+
- Customer rating and review count (4.8 ★ 324 reviews)
|
|
440
|
+
- Link to reviews section
|
|
441
|
+
- "Best seller" or "Top rated" badge
|
|
442
|
+
|
|
443
|
+
**Payment methods:**
|
|
444
|
+
- Accepted payment icons (Visa, Mastercard, PayPal, Apple Pay)
|
|
445
|
+
- Small icons (40px)
|
|
446
|
+
- Below "Add to Cart" or in footer
|
|
447
|
+
- Shows payment options available
|
|
448
|
+
|
|
449
|
+
**For new/unknown brands:**
|
|
450
|
+
- Customer testimonials
|
|
451
|
+
- "Join 10,000+ happy customers"
|
|
452
|
+
- Security badges (if legitimate - don't fake)
|
|
453
|
+
- Social proof (Instagram photos, user content)
|
|
454
|
+
- Clear contact information
|
|
455
|
+
|
|
456
|
+
**For high-value products:**
|
|
457
|
+
- Detailed specifications
|
|
458
|
+
- Professional photography
|
|
459
|
+
- Video demonstrations
|
|
460
|
+
- Warranty details prominently displayed
|
|
461
|
+
- Customer service contact visible
|
|
462
|
+
|
|
463
|
+
## Mobile Optimization
|
|
464
|
+
|
|
465
|
+
**Critical mobile patterns:**
|
|
466
|
+
|
|
467
|
+
**Sticky "Add to Cart" bar:**
|
|
468
|
+
- Fixed at bottom of screen
|
|
469
|
+
- Always accessible (no scrolling needed)
|
|
470
|
+
- Shows: Price + "Add to Cart" button
|
|
471
|
+
- Appears after scrolling past fold
|
|
472
|
+
- Higher conversion rates
|
|
473
|
+
|
|
474
|
+
**Image gallery:**
|
|
475
|
+
- Full-width swipeable carousel
|
|
476
|
+
- Pinch to zoom
|
|
477
|
+
- Dot indicators (1/5, 2/5)
|
|
478
|
+
- Tap to open full-screen view
|
|
479
|
+
|
|
480
|
+
**Variant selection:**
|
|
481
|
+
- Large touch targets (44-48px)
|
|
482
|
+
- Visual swatches easier than dropdowns
|
|
483
|
+
- Clear selected state
|
|
484
|
+
- Error messages visible
|
|
485
|
+
|
|
486
|
+
**Accordion for details:**
|
|
487
|
+
- Description, Specs, Shipping as accordion
|
|
488
|
+
- Starts collapsed (save space)
|
|
489
|
+
- User expands what they need
|
|
490
|
+
- Clear expand/collapse indicators
|
|
491
|
+
|
|
492
|
+
**Reviews section:**
|
|
493
|
+
- Expandable (start with 2-3 reviews)
|
|
494
|
+
- "Show more" button
|
|
495
|
+
- Filter by rating
|
|
496
|
+
- Star rating distribution chart
|
|
497
|
+
|
|
498
|
+
## Checklist
|
|
499
|
+
|
|
500
|
+
**Essential product detail page features:**
|
|
501
|
+
|
|
502
|
+
- [ ] High-quality product images with zoom
|
|
503
|
+
- [ ] Price displayed correctly (Medusa: use value as-is, not divided)
|
|
504
|
+
- [ ] Price shows "From $X" when no variant selected (X = minimum variant price)
|
|
505
|
+
- [ ] Variant selection required before adding to cart
|
|
506
|
+
- [ ] Variant selection updates: price, stock, image
|
|
507
|
+
- [ ] Disable unavailable variant options (gray out)
|
|
508
|
+
- [ ] Stock availability indicator (in stock, low stock, out of stock)
|
|
509
|
+
- [ ] "Only X left" shown when stock is low (<=5)
|
|
510
|
+
- [ ] Add to Cart disabled until variant selected
|
|
511
|
+
- [ ] Optimistic UI update (cart count updates immediately)
|
|
512
|
+
- [ ] Success feedback (toast, cart popup, or checkmark)
|
|
513
|
+
- [ ] Stay on product page after adding (don't navigate away)
|
|
514
|
+
- [ ] Error handling (out of stock, API failure)
|
|
515
|
+
- [ ] Product description and specifications
|
|
516
|
+
- [ ] Customer reviews and ratings
|
|
517
|
+
- [ ] Related products recommendations (similar, bought together)
|
|
518
|
+
- [ ] Trust signals (free shipping, returns, secure checkout)
|
|
519
|
+
- [ ] Payment method icons displayed
|
|
520
|
+
- [ ] Breadcrumb navigation
|
|
521
|
+
- [ ] Mobile: Swipeable image gallery
|
|
522
|
+
- [ ] Mobile: Accordion for product details
|
|
523
|
+
- [ ] Mobile: Sticky Add to Cart bar (optional but effective)
|
|
524
|
+
- [ ] Tabs on desktop, accordion on mobile (hybrid)
|
|
525
|
+
- [ ] Fast loading (<2s, optimize images)
|
|
526
|
+
- [ ] Keyboard accessible (tab through options, enter to add)
|
|
527
|
+
- [ ] ARIA labels on variant selection (role="group", aria-label)
|