Use as-is. Replace Inputs. Keep identifiers, paths, and events unchanged.
Brand Name: "<YOUR BRAND NAME>"
Aesthetic Theme: "<YOUR AESTHETIC THEME>"
Reference Sites:
- "<REF SITE 1>"
- "<REF SITE 2>"
- "<REF SITE 3>"Project: {Brand Name} Stack: Astro 4 SSR + React 18 + TypeScript + TailwindCSS + Shopify Storefront API + Netlify Package Manager: npm
Design System - Aesthetic: {Aesthetic Theme} - References: {Reference Sites} - Auto-generate cohesive palette, fonts, visuals - Mobile-first; WCAG 2.1 AA
Critical Developer Experience - npm install && npm run dev works with no Shopify setup - Demo Mode: cart works; API failures log warnings only - Visual Indicator: bottom-left “Demo Mode” linking to SETUP.md when Shopify not configured - Docs: README.md (demo mode) + SETUP.md (Shopify setup)
Shopify Integration (Stubs) - src/lib/types.ts (import type): Money, ProductVariant, Product, Collection, CartLineItem, Cart - src/lib/shopify.ts (graceful errors): createCart(), addToCart(cartId, variantId, quantity), updateCartLines(), removeCartLines() - src/lib/cart.ts (Zustand + createJSONStorage) - State: cart, isLoading, error, isOpen - Actions: init(), add(variantId, quantity), updateQuantity(lineId, quantity), remove(lineId), clear(), clearError() - UI: openCart(), closeCart(), toggleCart() - Hooks: useCartCount(), useCartLoading(), useCartError() - Demo: local persistence; console warnings only
Cart Implementation (Exact Pattern)
- CartDrawer.tsx: right drawer, backdrop, Esc handling, scroll lock
- Header: button dispatches 'toggle-cart'; badge id="cart-count"
- BaseLayout: include ; listen for 'toggle-cart'
- ProductCard: variantId format ${product.id}-variant-default; no full-card link wrappers intercepting clicks; ensure overlay/button z-index allows clicks
Standard Architecture - Folders: components/layout, components/ui, components/cart, lib, pages, styles - Config: strict TypeScript; server output; Netlify adapter - Env: .env.example placeholders only; Shopify domain placeholder your-store.myshopify.com
Required Output - Repo runs immediately in demo mode; clear path to full Shopify integration
BaseLayout.astro (DOMContentLoaded script) - dynamically import ../lib/cart - cartStore.init() - listen for 'toggle-cart' → cartStore.toggleCart() - subscribe to store → update element id="cart-count" (show “99+” if >99, hide when 0)
Header.astro - button calls global dispatchCartToggle() → dispatch CustomEvent('toggle-cart') - contains badge element id="cart-count" (initially hidden; shows when count > 0)
Root Include - at layout root
Demo Variant Convention
- ProductCard uses variantId: ${product.id}-variant-default
- createDemoVariant(variantId): returns complete ProductVariant with product info; productId = variantId.replace('-variant-default','')
-
Install: npm install -
Develop: npm run dev -
Build: npm run build && npm run preview -
Typecheck (optional): npm run typecheck
-
Cart: add/update/remove; badge updates; drawer toggles; persists via localStorage -
Demo Mode: indicator visible without Shopify env; API failures only warn in console -
Accessibility/Responsive: backdrop, Esc close; mobile working -
Build: npm run build succeeds
-
Event name: 'toggle-cart' -
Badge id: "cart-count" -
VariantId format: `${product.id}-variant-default` -
Keep specified file paths/names -
Demo mode works without Shopify credentials -
No user-facing errors in demo mode (console warnings only)