Initial commit
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
# Breadcrumbs Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [When to Use Breadcrumbs](#when-to-use-breadcrumbs)
|
||||
- [Ecommerce Breadcrumb Patterns](#ecommerce-breadcrumb-patterns)
|
||||
- [Mobile Breadcrumbs](#mobile-breadcrumbs)
|
||||
- [SEO Structured Data](#seo-structured-data)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Breadcrumbs show the user's location within the site hierarchy (Home → Category → Subcategory → Product). Critical for ecommerce navigation and SEO.
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build breadcrumbs with separators and links. This guide focuses on ecommerce-specific patterns.
|
||||
|
||||
### Key Requirements
|
||||
|
||||
- Show full path from homepage to current page
|
||||
- Each level clickable (except current page)
|
||||
- Position below navbar, above page title
|
||||
- Include structured data for SEO (JSON-LD)
|
||||
- Mobile-optimized (back link pattern)
|
||||
|
||||
## When to Use Breadcrumbs
|
||||
|
||||
**Use for:**
|
||||
- Product pages (Home → Category → Subcategory → Product)
|
||||
- Category pages (Home → Category → Subcategory)
|
||||
- Deep site hierarchies (3+ levels)
|
||||
- Large catalogs with many categories
|
||||
|
||||
**Don't use for:**
|
||||
- Homepage (no parent pages)
|
||||
- Flat site structures (1-2 levels)
|
||||
- Checkout flow (linear, not hierarchical)
|
||||
- Search results (not hierarchical)
|
||||
|
||||
## Ecommerce Breadcrumb Patterns
|
||||
|
||||
### Product Page Breadcrumbs
|
||||
|
||||
**Standard pattern:**
|
||||
- Home / Category / Subcategory / Product Name
|
||||
- Example: Home / Electronics / Laptops / Gaming Laptop Pro
|
||||
|
||||
**Key considerations:**
|
||||
- All levels except product name are clickable
|
||||
- Product name is current page (non-clickable, darker text)
|
||||
- Shows product's location in catalog
|
||||
|
||||
**Multiple category membership:**
|
||||
- If product in multiple categories, choose primary/canonical
|
||||
- Match category in URL or navigation path
|
||||
- Be consistent across site
|
||||
|
||||
### Category Page Breadcrumbs
|
||||
|
||||
**Standard pattern:**
|
||||
- Home / Parent Category / Current Category
|
||||
- Example: Home / Electronics / Laptops
|
||||
|
||||
**Current category:**
|
||||
- Non-clickable (plain text)
|
||||
- Visually distinct from links (darker or bold)
|
||||
|
||||
### Path Construction
|
||||
|
||||
**Hierarchy:**
|
||||
- Start with "Home" (or home icon)
|
||||
- Follow category hierarchy
|
||||
- End with current page
|
||||
- Maximum 5-6 levels (keep shallow)
|
||||
|
||||
**URL alignment:**
|
||||
- Breadcrumb path should match URL hierarchy
|
||||
- Consistent naming between URLs and breadcrumbs
|
||||
- Example: `/categories/electronics/laptops` → "Home / Electronics / Laptops"
|
||||
|
||||
## Mobile Breadcrumbs
|
||||
|
||||
### Mobile Pattern: Collapse to Back Link
|
||||
|
||||
**Recommended approach:**
|
||||
- Show only previous level as back link
|
||||
- Back arrow icon (←) + parent page name
|
||||
- Example: "← Gaming Laptops"
|
||||
|
||||
**Why:**
|
||||
- Saves vertical space on mobile
|
||||
- Clear affordance (back navigation)
|
||||
- Simpler than full breadcrumb trail
|
||||
- Mobile users have device back button
|
||||
|
||||
**Alternative: Truncated path**
|
||||
- Show "Home ... Current Page"
|
||||
- Hide middle levels
|
||||
- Balances space and context
|
||||
|
||||
## SEO Structured Data
|
||||
|
||||
**BreadcrumbList schema (CRITICAL)**: Add JSON-LD structured data. Breadcrumbs appear in search results, improves CTR, helps search engines understand site structure.
|
||||
|
||||
**Implementation**: schema.org BreadcrumbList with items array. Each item has position (1, 2, 3...), name, and URL. See seo.md for schema details.
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Positioned below navbar, above page title
|
||||
- [ ] Full path shown (Home → Category → Product)
|
||||
- [ ] All levels clickable except current page
|
||||
- [ ] Current page visually distinct (non-clickable, darker)
|
||||
- [ ] Clear separators (›, /, > or chevron)
|
||||
- [ ] Mobile: Back link pattern ("← Category")
|
||||
- [ ] Structured data (JSON-LD BreadcrumbList)
|
||||
- [ ] Semantic HTML (`<nav aria-label="Breadcrumb">`)
|
||||
- [ ] `aria-current="page"` on current item
|
||||
- [ ] Keyboard accessible (tab through links)
|
||||
- [ ] Truncate long labels (20-30 characters max)
|
||||
- [ ] Consistent with navigation labels
|
||||
- [ ] Maximum 5-6 levels deep
|
||||
@@ -0,0 +1,189 @@
|
||||
# Cart Popup Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [When to Show Cart Popup](#when-to-show-cart-popup)
|
||||
- [Layout Patterns](#layout-patterns)
|
||||
- [Cart Display](#cart-display)
|
||||
- [Actions and CTAs](#actions-and-ctas)
|
||||
- [Empty State](#empty-state)
|
||||
- [Mobile Considerations](#mobile-considerations)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Cart popup (mini cart/cart drawer) shows quick cart overview without navigating away. Opens from cart icon click or after adding items.
|
||||
|
||||
**⚠️ CRITICAL: Always display variant details (size, color, material, etc.) in cart popup, not just product titles.**
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build modals, dialogs, and overlays. This focuses on ecommerce-specific patterns.
|
||||
|
||||
**Cart popup vs full cart page:**
|
||||
- Popup: Quick overview, fast checkout path, continue shopping easily
|
||||
- Full page: Detailed review, promo codes, complex operations
|
||||
- **Recommended**: Both - popup for speed, full cart page for details
|
||||
|
||||
## When to Show Cart Popup
|
||||
|
||||
**Trigger options:**
|
||||
|
||||
1. **On cart icon click** (always) - Click cart icon in navbar opens popup
|
||||
2. **After adding to cart** (recommended) - Auto-open popup when item added, confirms action, allows checkout or continue shopping
|
||||
3. **Hover cart icon** (desktop only, optional) - Quick peek on hover. Can be accidental, not recommended.
|
||||
|
||||
**Add-to-cart feedback alternatives:**
|
||||
- Show popup (most common) - Immediate confirmation, clear path to checkout
|
||||
- Toast only (less intrusive) - Small notification, user clicks cart icon to see details
|
||||
- Navigate to cart page (traditional) - Goes directly to full cart page, less common now
|
||||
|
||||
## Layout Patterns
|
||||
|
||||
**Two common patterns:**
|
||||
|
||||
**1. Dropdown (recommended for simplicity):**
|
||||
- Drops down from cart icon, positioned below navbar
|
||||
- Width: 280-320px, max height with scroll
|
||||
- No backdrop overlay (click outside to close)
|
||||
- Better for few items, simpler implementation
|
||||
|
||||
**2. Slide-in drawer (more prominent):**
|
||||
- Slides from right, full height, width 320-400px (desktop) or 80-90% (mobile)
|
||||
- Semi-transparent backdrop overlay (click to close)
|
||||
- Better for multiple items or complex carts
|
||||
|
||||
**Both patterns have:**
|
||||
- Header: Title + item count + close button (optional for dropdown)
|
||||
- Scrollable content: List of cart items
|
||||
- Sticky footer: Subtotal + action buttons (Checkout, View Cart)
|
||||
|
||||
## Cart Display
|
||||
|
||||
**Fetch cart data from backend:**
|
||||
- Cart ID from localStorage
|
||||
- Line items (products, variants, quantities, prices)
|
||||
- Cart totals (subtotal, tax, shipping)
|
||||
- See connecting-to-backend.md for backend integration
|
||||
|
||||
**When to fetch:**
|
||||
- On app initialization (update cart icon badge)
|
||||
- On popup open (show loading state)
|
||||
- After cart updates (add/remove/change quantity)
|
||||
|
||||
**State management:**
|
||||
- Store cart data globally (React Context or TanStack Query)
|
||||
- Persist cart ID in localStorage
|
||||
- Optimistic UI updates (update immediately, revert on error)
|
||||
- **CRITICAL: Clear cart state after order is placed** - See connecting-to-backend.md for cart cleanup pattern
|
||||
- Common issue: Cart popup shows old items after checkout because cart state wasn't cleared
|
||||
- See connecting-to-backend.md for cart state patterns
|
||||
|
||||
**Cart item display:**
|
||||
|
||||
**CRITICAL: Always show variant details (size, color, material, etc.) for each cart item.**
|
||||
|
||||
Without variant details, users can't confirm they added the correct variant. This is especially critical when products have multiple options.
|
||||
|
||||
- Product image (60-80px thumbnail)
|
||||
- Product title (truncated to 2 lines)
|
||||
- **Variant details (REQUIRED)**: Size, color, material, or other variant options
|
||||
- Format: "Size: Large, Color: Black" or "Large / Black"
|
||||
- Show ALL selected variant options, not just product title
|
||||
- Display below title, smaller text (gray)
|
||||
- Quantity controls (+/- buttons, debounce 300-500ms)
|
||||
- Unit price and total price (line item total = price × quantity)
|
||||
- Remove button (X icon, no confirmation needed)
|
||||
|
||||
**Why variant details are critical:**
|
||||
- User confirmation: "Did I add the right size?"
|
||||
- Prevents cart abandonment from uncertainty
|
||||
- Allows corrections before checkout
|
||||
- Essential for products with multiple variants (clothing, shoes, configurable products)
|
||||
|
||||
## Actions and CTAs
|
||||
|
||||
**Cart summary display:**
|
||||
- Subtotal (sum of all items)
|
||||
- Shipping and tax: "Calculated at checkout" or actual amount
|
||||
- Total: Bold and prominent
|
||||
|
||||
**Free shipping indicator (optional):**
|
||||
- "Add $25 more for free shipping" with progress bar
|
||||
- Encourages larger orders, updates as cart changes
|
||||
|
||||
**Promo codes:**
|
||||
- Usually NOT in cart popup (too cramped)
|
||||
- Reserve for full cart page
|
||||
- Exception: Simple code input if space permits
|
||||
|
||||
**Action buttons:**
|
||||
1. **Checkout** (primary) - Most prominent, high contrast (brand color), navigates to checkout
|
||||
2. **View Cart** (secondary) - Outline or subtle, navigates to full cart page
|
||||
|
||||
Both buttons full-width, 44-48px height on mobile.
|
||||
|
||||
## Empty State
|
||||
|
||||
Show icon/illustration + "Your cart is empty" + "Continue Shopping" button. Centered, friendly, minimal design.
|
||||
|
||||
## Loading and Error States
|
||||
|
||||
**On popup open**: Show skeleton/placeholder while fetching (avoid blank screen)
|
||||
|
||||
**During updates**:
|
||||
- Quantity changes: Inline spinner, disable controls, debounce 300-500ms
|
||||
- Item removal: Fade out animation, disable remove button during request
|
||||
- Add to cart: Loading indicator on button ("Adding...")
|
||||
|
||||
**Error handling**:
|
||||
- Network errors: Show retry option, don't close popup
|
||||
- Invalid cart ID: Create new cart automatically
|
||||
- Out of stock: Disable quantity increase, show message
|
||||
- Revert optimistic updates on failure
|
||||
|
||||
**Animations**: Smooth transitions (250-350ms), slide-in drawer, backdrop fade-in/out. Highlight newly added items.
|
||||
|
||||
## Mobile Considerations
|
||||
|
||||
**Dropdown on mobile:**
|
||||
- Full-width (100% minus margins)
|
||||
- Max height 60-70% viewport, scrollable
|
||||
- Tap outside to close
|
||||
|
||||
**Drawer on mobile:**
|
||||
- 85-95% screen width or full screen
|
||||
- Slides from right or bottom
|
||||
- Swipe to close gesture supported
|
||||
- Backdrop overlay
|
||||
|
||||
**Mobile adjustments:**
|
||||
- Large touch targets (44-48px minimum)
|
||||
- Full-width action buttons (48-52px height)
|
||||
- Smaller images (60px), truncate titles
|
||||
- Sticky footer with actions
|
||||
- Large close button (44x44px)
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
- [ ] Opens on cart icon click
|
||||
- [ ] Dropdown (280-320px) or drawer (320-400px) layout
|
||||
- [ ] Close button or click outside to close
|
||||
- [ ] Backdrop overlay if drawer
|
||||
- [ ] **CRITICAL: Cart items show variant details (size, color, etc.) - not just product title**
|
||||
- [ ] Cart items with image, title, variant options, quantity, prices
|
||||
- [ ] Quantity controls (+/- buttons, debounced)
|
||||
- [ ] Remove item button
|
||||
- [ ] Subtotal displayed
|
||||
- [ ] Checkout button (primary)
|
||||
- [ ] View Cart button (secondary)
|
||||
- [ ] Empty state with "Continue Shopping" CTA
|
||||
- [ ] Loading states (skeleton/spinner)
|
||||
- [ ] Smooth animations (250-350ms)
|
||||
- [ ] Mobile: Full-width dropdown or 85-95% drawer
|
||||
- [ ] Touch targets 44-48px minimum
|
||||
- [ ] `role="dialog"` and `aria-modal="true"`
|
||||
- [ ] ARIA labels on cart button ("Shopping cart with 3 items")
|
||||
- [ ] Keyboard accessible (focus trap, Escape closes, return focus)
|
||||
- [ ] Screen reader announcements (item added/removed)
|
||||
- [ ] Real-time cart count badge updates
|
||||
@@ -0,0 +1,298 @@
|
||||
# Country Selector Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [When to Implement](#when-to-implement)
|
||||
- [UI Patterns](#ui-patterns)
|
||||
- [State Management](#state-management)
|
||||
- [Backend Integration](#backend-integration)
|
||||
- [Detection and Defaults](#detection-and-defaults)
|
||||
- [Mobile Considerations](#mobile-considerations)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Country selector allows customers to choose their country/region, which determines currency, pricing, available products, shipping options, payment methods, and localized content.
|
||||
|
||||
### Key Ecommerce Functions
|
||||
|
||||
- Display prices in correct currency
|
||||
- Show country-specific product availability
|
||||
- Apply region-specific promotions and discounts
|
||||
- Calculate accurate shipping costs and delivery times
|
||||
- Enable appropriate payment methods
|
||||
- Display localized content and language
|
||||
|
||||
### Purpose
|
||||
|
||||
**Why country/region selection matters:**
|
||||
- Prices vary by region (currency, taxes, import fees)
|
||||
- Product availability differs by market
|
||||
- Shipping methods and costs are region-specific
|
||||
- Legal requirements vary (privacy, consumer protection)
|
||||
- Payment methods differ by country
|
||||
- Improves user experience with relevant content
|
||||
|
||||
## When to Implement
|
||||
|
||||
**Implement country selector when:**
|
||||
- Backend supports multiple countries or regions
|
||||
- Selling to multiple countries or regions
|
||||
- Prices vary by location (currency, taxes)
|
||||
- International shipping with different rates
|
||||
- Region-specific product catalogs
|
||||
- Multi-currency support needed
|
||||
- Legal or regulatory requirements vary by region
|
||||
|
||||
**Skip if:**
|
||||
- Backend doesn't support multiple countries or regions
|
||||
- All prices in one currency
|
||||
- No regional differences in catalog or pricing
|
||||
|
||||
## UI Patterns
|
||||
|
||||
### Placement Options
|
||||
|
||||
**Footer placement (modern and minimal):**
|
||||
- Bottom of page in footer
|
||||
- Less prominent but always accessible
|
||||
- Icon (flag or globe) + country code/name
|
||||
|
||||
**Header placement (most common):**
|
||||
- Top-right of navigation bar
|
||||
- Icon (flag or globe) + country code/name
|
||||
- Click opens dropdown or modal selector
|
||||
|
||||
**Modal/popup on first visit:**
|
||||
- Detect location and suggest country
|
||||
- Allow user to confirm or change
|
||||
- Store preference for future visits
|
||||
|
||||
### Selector Design Patterns
|
||||
|
||||
**Pattern 1: Dropdown (Recommended)**
|
||||
|
||||
Small, compact selector in header. Shows current country flag/name, click to open dropdown with country list.
|
||||
|
||||
**Pros:** Doesn't interrupt browsing, always accessible, familiar pattern.
|
||||
|
||||
**Pattern 2: Modal on First Visit**
|
||||
|
||||
Full-screen or centered modal on first visit. "Select your country to see accurate prices and shipping."
|
||||
|
||||
**Pros:** Forces initial selection, ensures accurate pricing from start.
|
||||
**Cons:** Can be intrusive, delays browsing.
|
||||
|
||||
**Tradeoff:** Modal ensures selection but adds friction. Dropdown is less intrusive but users may miss it.
|
||||
|
||||
**Pattern 3: Inline Banner**
|
||||
|
||||
Sticky banner at top: "Shipping to United States? Change" with link to selector.
|
||||
|
||||
**Pros:** Non-intrusive reminder, doesn't block content.
|
||||
**Cons:** Takes vertical space, easy to ignore.
|
||||
|
||||
### Country List Display
|
||||
|
||||
**Search + list:**
|
||||
- Search input at top
|
||||
- Alphabetical country list below
|
||||
- Popular countries at top (US, UK, Canada, etc.)
|
||||
- Flag icons for visual recognition
|
||||
|
||||
**Grouped by region:**
|
||||
- North America, Europe, Asia, etc.
|
||||
- Collapsible sections
|
||||
- Helpful for large lists (100+ countries)
|
||||
|
||||
**Format:**
|
||||
```
|
||||
🇺🇸 United States (USD)
|
||||
🇬🇧 United Kingdom (GBP)
|
||||
🇨🇦 Canada (CAD)
|
||||
───────────────────
|
||||
🇩🇪 Germany (EUR)
|
||||
🇫🇷 France (EUR)
|
||||
```
|
||||
|
||||
Show flag, country name, and currency code for clarity.
|
||||
|
||||
## State Management
|
||||
|
||||
### Storing Country Selection
|
||||
|
||||
**Client-side storage (recommended):**
|
||||
- localStorage or cookies
|
||||
- Persists across sessions
|
||||
- Key: `region_id` or `country_code`
|
||||
|
||||
**Why local storage:**
|
||||
- Fast access without API call
|
||||
- Available immediately on page load
|
||||
- No server round-trip needed
|
||||
|
||||
### Context Provider Pattern
|
||||
|
||||
**Recommended: Create context for region/country data.**
|
||||
|
||||
Provides quick access throughout the app to:
|
||||
- Selected country
|
||||
- Selected region (if applicable)
|
||||
- Currency
|
||||
- Available payment methods
|
||||
- Shipping options
|
||||
|
||||
**Benefits:**
|
||||
- Centralized country/region logic
|
||||
- Easy access from any component
|
||||
- Single source of truth
|
||||
- Simplified cart and product queries
|
||||
|
||||
**Example structure:**
|
||||
```typescript
|
||||
interface RegionContext {
|
||||
country: string
|
||||
region?: string
|
||||
currency: string
|
||||
changeCountry: (country: string) => void
|
||||
}
|
||||
```
|
||||
|
||||
### When to Apply Selection
|
||||
|
||||
**Apply country/region to:**
|
||||
- Product price display (convert currency, apply regional pricing)
|
||||
- Cart creation (set region for accurate totals)
|
||||
- Product queries (retrieve accurate pricing)
|
||||
- Checkout flow (shipping methods, payment options)
|
||||
- Content display (language, measurements)
|
||||
|
||||
## Backend Integration
|
||||
|
||||
### General Backend Requirements
|
||||
|
||||
**What backend needs to provide:**
|
||||
- List of available countries/regions
|
||||
- Mapping of countries to regions (if using regional structure)
|
||||
- Pricing per region or country
|
||||
- Product availability by region
|
||||
- Shipping methods by region
|
||||
- Supported payment methods by region
|
||||
|
||||
**API considerations:**
|
||||
- Fetch country/region list on app load
|
||||
- Pass selected country/region to product queries
|
||||
- Include region in cart creation
|
||||
- Validate country selection on backend
|
||||
|
||||
### Medusa Backend Integration
|
||||
|
||||
**For Medusa users, regions are critical for accurate pricing.**
|
||||
|
||||
Medusa uses regions (not individual countries) for pricing. A region can contain multiple countries.
|
||||
|
||||
**Key concepts:**
|
||||
- **Region**: Group of countries with shared pricing (e.g., "Europe" region)
|
||||
- **Country**: Individual country within a region
|
||||
- **Currency**: Each region has one currency
|
||||
|
||||
**Mapping country to region:**
|
||||
1. Customer selects country (e.g., "Germany")
|
||||
2. Find which region contains that country (e.g., "Europe" region)
|
||||
3. Store region ID for cart and product operations
|
||||
4. Use region for all pricing queries
|
||||
|
||||
**Required for:**
|
||||
- Creating carts: Must pass region ID
|
||||
- Retrieving products: Pass region to get accurate prices
|
||||
- Product availability: Products may be region-specific
|
||||
|
||||
**Implementation pattern:**
|
||||
Create a context that stores both country and region. When country changes, look up corresponding region and update both.
|
||||
|
||||
**For detailed Medusa region implementation, see:**
|
||||
- Medusa storefront regions documentation: https://docs.medusajs.com/resources/storefront-development/regions/context
|
||||
- Medusa JS SDK regions endpoints
|
||||
- Consult Medusa MCP server for real-time API details
|
||||
|
||||
**Other backends:**
|
||||
Check the ecommerce backend's documentation for country/region handling patterns.
|
||||
|
||||
## Detection and Defaults
|
||||
|
||||
### Auto-Detection
|
||||
|
||||
**IP-based geolocation (recommended):**
|
||||
Detect user's country from IP address. Use as default but allow user to change.
|
||||
|
||||
**Implementation:**
|
||||
- Use geolocation API or service (MaxMind, ipapi.co, CloudFlare)
|
||||
- Server-side detection (more accurate)
|
||||
- Set as default, show confirmation: "Shipping to United States?"
|
||||
|
||||
**Benefits:** Reduces friction, most users keep detected country.
|
||||
|
||||
**Tradeoff:** Not 100% accurate (VPNs, proxies). Always allow manual override.
|
||||
|
||||
### Fallback Strategy
|
||||
|
||||
**If detection fails or unavailable:**
|
||||
1. Check localStorage for previous selection
|
||||
2. Use browser language as hint (`navigator.language`)
|
||||
3. Default to primary market (e.g., US for US-based store)
|
||||
4. Prompt user to select on first interaction (cart, checkout)
|
||||
|
||||
**Never block browsing if country unknown.**
|
||||
Allow browsing with default pricing, prompt selection before checkout.
|
||||
|
||||
## Mobile Considerations
|
||||
|
||||
**Selector placement:**
|
||||
Mobile hamburger menu or bottom of page. Top-right in mobile header if space allows.
|
||||
|
||||
**Modal selector:**
|
||||
Full-screen modal on mobile for country selection. Large touch targets (48px), search input at top, easy scrolling.
|
||||
|
||||
**Sticky reminder:**
|
||||
Small banner: "Shipping to US? Change" with tap to open selector.
|
||||
|
||||
**Detection prompt:**
|
||||
Bottom sheet: "We detected you're in Germany. Is this correct?" with Confirm/Change buttons.
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Country selector visible (header, footer, or first-visit modal)
|
||||
- [ ] Current country clearly displayed (flag, name, currency)
|
||||
- [ ] Dropdown or modal with country list
|
||||
- [ ] Search functionality for long country lists
|
||||
- [ ] Popular countries at top of list
|
||||
- [ ] Flag icons for visual recognition
|
||||
- [ ] Show currency code per country
|
||||
- [ ] localStorage persistence (save selection)
|
||||
- [ ] Context provider for region/country data
|
||||
- [ ] Auto-detection based on IP (optional)
|
||||
- [ ] Manual override always available
|
||||
- [ ] Apply to product prices (currency, regional pricing)
|
||||
- [ ] Apply to cart creation (set region)
|
||||
- [ ] Apply to checkout (shipping, payment methods)
|
||||
- [ ] Fallback if detection fails
|
||||
- [ ] Mobile: Full-screen modal or bottom sheet
|
||||
- [ ] Mobile: Large touch targets (48px)
|
||||
- [ ] Backend integration (fetch regions, map countries)
|
||||
- [ ] For Medusa: Region context with country-to-region mapping
|
||||
- [ ] For Medusa: Pass region to cart and product queries
|
||||
- [ ] ARIA label on selector button
|
||||
- [ ] Keyboard accessible (Tab, Enter, arrows)
|
||||
- [ ] Screen reader announces country changes
|
||||
|
||||
**Optional enhancements:**
|
||||
|
||||
- [ ] Currency conversion display (show original + converted)
|
||||
- [ ] Language selector tied to country
|
||||
- [ ] Shipping estimate based on country
|
||||
- [ ] Tax estimation display
|
||||
- [ ] Regional content (images, messaging)
|
||||
- [ ] "Not shipping to your country?" alternative
|
||||
@@ -0,0 +1,112 @@
|
||||
# Footer Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Essential Footer Elements](#essential-footer-elements)
|
||||
- [Dynamic Category Links (Ecommerce-Specific)](#dynamic-category-links-ecommerce-specific)
|
||||
- [Newsletter Signup](#newsletter-signup)
|
||||
- [Payment and Trust Badges](#payment-and-trust-badges)
|
||||
- [Mobile Footer](#mobile-footer)
|
||||
|
||||
## Overview
|
||||
|
||||
Footer provides supplementary navigation, company info, and trust signals. Appears on every page.
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build multi-column layouts and navigation lists. This guide focuses on ecommerce footer patterns.
|
||||
|
||||
### Key Requirements
|
||||
|
||||
- Navigation links (categories, pages)
|
||||
- Dynamic category fetching from backend
|
||||
- Legal links (Privacy, Terms)
|
||||
- Newsletter signup
|
||||
- Payment method badges
|
||||
- Social media links
|
||||
- Responsive (multi-column desktop, single-column mobile)
|
||||
|
||||
## Essential Footer Elements
|
||||
|
||||
### Must-Have Content
|
||||
|
||||
**Required:**
|
||||
- Navigation links (categories from backend)
|
||||
- Contact information (email, phone)
|
||||
- Legal links (Privacy Policy, Terms of Service)
|
||||
- Copyright notice with current year
|
||||
|
||||
**Strongly recommended:**
|
||||
- Newsletter signup form
|
||||
- Payment method badges
|
||||
- Social media links
|
||||
- Trust signals
|
||||
|
||||
### Multi-Column Layout (Desktop)
|
||||
|
||||
**Standard pattern: 4-5 columns**
|
||||
- Column 1: Shop/Categories (dynamic from backend)
|
||||
- Column 2: Customer Service (Contact, FAQ, Shipping)
|
||||
- Column 3: Company (About, Careers)
|
||||
- Column 4: Newsletter signup
|
||||
- Bottom: Legal links, payment badges, copyright
|
||||
|
||||
## Dynamic Category Links (Ecommerce-Specific)
|
||||
|
||||
**CRITICAL: Fetch categories from backend dynamically** - never hardcode. Fetch from ecommerce backend API (for Medusa: `sdk.store.category.list()`).
|
||||
|
||||
**Benefits:**
|
||||
- Stays in sync with main navigation
|
||||
- Categories added/removed automatically
|
||||
- No manual footer updates
|
||||
|
||||
**Guidelines:**
|
||||
- Show top-level categories only (5-8 max)
|
||||
- Match labels from main navigation
|
||||
- Cache category data (rarely changes)
|
||||
|
||||
## Newsletter Signup
|
||||
|
||||
**Essential elements:**
|
||||
- Email input + submit button ("Subscribe")
|
||||
- **Value proposition (CRITICAL)**: State clear benefit ("Get 10% off your first order", "Exclusive deals + early access"). Don't just say "Subscribe to newsletter".
|
||||
- Privacy note: "We respect your privacy" + link to privacy policy
|
||||
|
||||
**Layout:** Input + button inline (desktop), stacked (mobile). Full width on mobile.
|
||||
|
||||
## Payment and Trust Badges
|
||||
|
||||
**Payment method icons:**
|
||||
Display accepted payments (Visa, Mastercard, PayPal, Apple Pay, Google Pay). 40-50px icons, horizontal row, bottom of footer.
|
||||
|
||||
**Trust badges (optional):**
|
||||
Max 3-4 legitimate certifications (SSL, BBB, money-back guarantee). Only use real badges with verification links.
|
||||
|
||||
## Mobile Footer
|
||||
|
||||
**Single column, stacked:** Logo → Navigation → Newsletter → Social → Legal/copyright.
|
||||
|
||||
**Collapsible sections (optional):** Accordion pattern for navigation to reduce height. Keep newsletter/social always visible.
|
||||
|
||||
**Touch-friendly:** 44px minimum links, 8-12px spacing, 14-16px text, 48px newsletter input height.
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Navigation links (categories, pages)
|
||||
- [ ] Categories fetched dynamically from backend
|
||||
- [ ] Contact information (email, phone)
|
||||
- [ ] Legal links (Privacy Policy, Terms of Service)
|
||||
- [ ] Copyright notice with current year
|
||||
- [ ] Newsletter signup form with value proposition
|
||||
- [ ] Payment method icons
|
||||
- [ ] Social media links
|
||||
- [ ] Responsive (4-5 columns desktop, single-column mobile)
|
||||
- [ ] Mobile: 44px touch targets
|
||||
- [ ] Mobile: Collapsible sections (optional)
|
||||
- [ ] Semantic HTML (`<footer>`, `<nav>` sections)
|
||||
- [ ] ARIA labels on navigation ("Footer navigation")
|
||||
- [ ] Keyboard accessible
|
||||
- [ ] Visible focus indicators
|
||||
- [ ] Color contrast 4.5:1 minimum
|
||||
- [ ] Consistent across all pages
|
||||
@@ -0,0 +1,241 @@
|
||||
# Hero Section Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Hero Types and When to Use](#hero-types-and-when-to-use)
|
||||
- [Content Guidelines](#content-guidelines)
|
||||
- [Multiple Heroes (Carousel)](#multiple-heroes-carousel)
|
||||
- [Mobile Hero](#mobile-hero)
|
||||
- [Performance](#performance)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Hero section is the prominent banner at top of homepage, immediately below navigation. First content users see - sets tone for shopping experience.
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build full-width banners with images and text overlays. This focuses on ecommerce hero patterns.
|
||||
|
||||
**Key requirements:**
|
||||
- Above the fold (immediately visible)
|
||||
- Clear value proposition or promotional message
|
||||
- High-quality imagery
|
||||
- Strong call-to-action
|
||||
- Fast loading (critical for first impression)
|
||||
|
||||
## Hero Types and When to Use
|
||||
|
||||
### 1. Full-Width Banner (Most Common)
|
||||
|
||||
**Characteristics:**
|
||||
- Spans entire viewport width
|
||||
- Large background image or video
|
||||
- Text overlay with headline + CTA
|
||||
- Single focused message
|
||||
|
||||
**Best for:**
|
||||
- Seasonal campaigns ("Summer Sale")
|
||||
- New product arrivals
|
||||
- Brand storytelling
|
||||
- Single promotional focus
|
||||
- Simple, bold message
|
||||
|
||||
**Example:** Background image of products, headline "40% Off Summer Sale", CTA "Shop Now"
|
||||
|
||||
### 2. Split Hero (Image + Content)
|
||||
|
||||
**Characteristics:**
|
||||
- 50/50 or 60/40 split layout
|
||||
- Image on one side, text content on other
|
||||
- No text overlay on image
|
||||
- Cleaner, easier to read
|
||||
|
||||
**Best for:**
|
||||
- Product launches (show product clearly)
|
||||
- Detailed messaging (more text space)
|
||||
- Accessibility (no text-on-image contrast issues)
|
||||
- Professional/B2B stores
|
||||
|
||||
**Example:** Product image (left 50%), headline + benefits + CTA (right 50%)
|
||||
|
||||
### 3. Minimal Hero
|
||||
|
||||
**Characteristics:**
|
||||
- Large image, minimal text
|
||||
- Image does storytelling
|
||||
- Subtle headline, small CTA
|
||||
- Emphasis on visual brand
|
||||
|
||||
**Best for:**
|
||||
- Luxury brands (sophisticated aesthetic)
|
||||
- Lifestyle brands (aspirational imagery)
|
||||
- Photography-focused products
|
||||
- Brand over promotion
|
||||
|
||||
### 4. Video Hero
|
||||
|
||||
**Characteristics:**
|
||||
- Background video (muted, looping)
|
||||
- Text overlay on video
|
||||
- Fallback image for slow connections
|
||||
|
||||
**Best for:**
|
||||
- Fashion brands (show products in motion)
|
||||
- Lifestyle products (demonstrate usage)
|
||||
- High-budget campaigns
|
||||
- Brand storytelling with motion
|
||||
|
||||
**Important:** Auto-play muted, provide play/pause controls, optimize file size (<5MB), use poster image fallback.
|
||||
|
||||
### 5. Product Showcase Hero
|
||||
|
||||
**Characteristics:**
|
||||
- Multiple featured products in hero
|
||||
- Grid of 2-4 products
|
||||
- Quick links to product pages
|
||||
- Less promotional, more discovery
|
||||
|
||||
**Best for:**
|
||||
- Multi-category stores
|
||||
- Product-focused (not campaign-focused)
|
||||
- Quick product discovery
|
||||
- Minimal marketing, maximum browsing
|
||||
|
||||
## Content Guidelines
|
||||
|
||||
**Headline best practices:**
|
||||
- Short and impactful (5-10 words)
|
||||
- Clear value proposition ("Free Shipping on All Orders")
|
||||
- Urgency if time-sensitive ("48-Hour Flash Sale")
|
||||
- Benefit-focused ("Upgrade Your Style")
|
||||
- Avoid generic ("Welcome to Our Store")
|
||||
|
||||
**Subtext (optional):**
|
||||
- 10-20 words maximum
|
||||
- Expand on headline benefit
|
||||
- Add context or details
|
||||
- Not always necessary (clean design)
|
||||
|
||||
**Call-to-action:**
|
||||
- Single primary CTA button
|
||||
- Action-oriented text ("Shop Now", "Explore Category", "Get Started")
|
||||
- High contrast (stands out on image)
|
||||
- Large enough (48px height minimum)
|
||||
- Link to relevant landing page (sale, category, product listing)
|
||||
|
||||
**Image selection:**
|
||||
- High quality, professional photography
|
||||
- Shows products or lifestyle context
|
||||
- Represents brand aesthetic
|
||||
- Optimized for web (<500KB)
|
||||
- Responsive (different crops for mobile)
|
||||
- Ensure text overlay is readable (adequate contrast)
|
||||
|
||||
## Multiple Heroes (Carousel)
|
||||
|
||||
**Carousel pattern:**
|
||||
- 2-4 slides rotating automatically
|
||||
- Each slide = independent hero (own message, image, CTA)
|
||||
- Auto-rotate every 5-7 seconds (slow enough to read)
|
||||
- Manual controls (prev/next arrows, dot indicators)
|
||||
- Pause on hover (accessibility)
|
||||
|
||||
**When to use carousel:**
|
||||
- Multiple concurrent campaigns (Winter Sale + New Arrivals)
|
||||
- Different audience segments (Men/Women/Kids)
|
||||
- Seasonal variety showcase
|
||||
- Limited above-fold space
|
||||
|
||||
**When NOT to use carousel:**
|
||||
- Single focused campaign (just use one hero)
|
||||
- Users rarely see slides beyond first (carousel blindness)
|
||||
- Slower page load (multiple images)
|
||||
- Accessibility concerns (auto-rotating content)
|
||||
|
||||
**Carousel best practices:**
|
||||
- Max 3-4 slides (more = ignored)
|
||||
- First slide most important (most viewed)
|
||||
- Consistent layout across slides
|
||||
- Clear indicators showing progress
|
||||
- Don't rely on later slides for critical info
|
||||
- Pause on interaction (hover, focus)
|
||||
|
||||
## Mobile Hero
|
||||
|
||||
**Mobile adjustments (CRITICAL):**
|
||||
|
||||
**Layout:**
|
||||
- Full-width, portrait aspect (2:3 or 3:4)
|
||||
- Vertical composition (text overlays center/bottom)
|
||||
- Larger text for readability
|
||||
- Simplified message (shorter headline)
|
||||
|
||||
**Split hero on mobile:**
|
||||
- Stack vertically (image top, text bottom)
|
||||
- Don't use side-by-side (too cramped)
|
||||
|
||||
**Performance:**
|
||||
- Smaller images (<300KB)
|
||||
- Different image crop for mobile portrait
|
||||
- Use `srcset` or `<picture>` for responsive images
|
||||
- Consider static image instead of video (mobile data)
|
||||
|
||||
**Touch interactions:**
|
||||
- Large CTA button (48px height minimum)
|
||||
- Easy carousel controls (if used)
|
||||
- Swipe gesture for carousel slides
|
||||
|
||||
## Performance
|
||||
|
||||
**Critical for first impression:**
|
||||
|
||||
**Image optimization:**
|
||||
- WebP format with JPEG fallback
|
||||
- Lazy load below-fold content (not hero - it's above fold)
|
||||
- Responsive images (mobile gets smaller size)
|
||||
- Target: <500KB desktop, <300KB mobile
|
||||
- Use CDN for faster delivery
|
||||
|
||||
**Video optimization:**
|
||||
- <5MB file size maximum
|
||||
- Muted, autoplay, loop
|
||||
- Poster image (shows before video loads)
|
||||
- Fallback to image on slow connections
|
||||
- Consider not using on mobile (data/performance)
|
||||
|
||||
**LCP optimization:**
|
||||
- Hero image is often Largest Contentful Paint
|
||||
- Preload hero image: `<link rel="preload" as="image" href="hero.jpg">`
|
||||
- Inline critical CSS for hero
|
||||
- Avoid layout shift (set image dimensions)
|
||||
|
||||
**Target metrics:**
|
||||
- LCP < 2.5 seconds
|
||||
- No layout shift (CLS < 0.1)
|
||||
- Fast interaction (hero CTA clickable immediately)
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Above the fold (immediately visible)
|
||||
- [ ] Clear headline (5-10 words, value proposition)
|
||||
- [ ] High-quality image (professional, on-brand)
|
||||
- [ ] Primary CTA button (action-oriented, high contrast)
|
||||
- [ ] Fast loading (<500KB image desktop, <300KB mobile)
|
||||
- [ ] Responsive images (different sizes/crops for devices)
|
||||
- [ ] Mobile: Portrait aspect ratio (2:3 or 3:4)
|
||||
- [ ] Mobile: Vertical text placement (center/bottom)
|
||||
- [ ] Mobile: Large CTA (48px height minimum)
|
||||
- [ ] Text overlay readable (adequate contrast, background overlay)
|
||||
- [ ] If carousel: Max 3-4 slides
|
||||
- [ ] If carousel: Auto-rotate 5-7 seconds
|
||||
- [ ] If carousel: Pause on hover/focus
|
||||
- [ ] If carousel: Manual controls (arrows, dots)
|
||||
- [ ] If video: Muted, autoplay, loop
|
||||
- [ ] If video: Poster image fallback
|
||||
- [ ] If video: <5MB file size
|
||||
- [ ] Preload hero image (LCP optimization)
|
||||
- [ ] No layout shift (set image dimensions)
|
||||
- [ ] ARIA labels on carousel controls
|
||||
- [ ] Keyboard accessible (Tab to CTA, arrow keys for carousel)
|
||||
@@ -0,0 +1,239 @@
|
||||
# Megamenu Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [When to Use Megamenu](#when-to-use-megamenu)
|
||||
- [Content Organization](#content-organization)
|
||||
- [Layout Patterns](#layout-patterns)
|
||||
- [Trigger Behavior](#trigger-behavior)
|
||||
- [Mobile Alternative](#mobile-alternative)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Megamenu is a large, full-width dropdown navigation showing multiple columns of categories, links, and promotional content. Opens from navbar trigger items (e.g., "Shop", "Men", "Women").
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build dropdown menus with hover/click triggers. This focuses on ecommerce megamenu patterns.
|
||||
|
||||
**Key requirements:**
|
||||
- Full-width display (spans viewport)
|
||||
- Multiple columns for categories
|
||||
- Positioned directly below navbar
|
||||
- Optional promotional images
|
||||
- Mobile alternative (hamburger menu, not megamenu)
|
||||
|
||||
## When to Use Megamenu
|
||||
|
||||
**Use megamenu when:**
|
||||
- Large product catalog (10+ top-level categories)
|
||||
- Deep hierarchy (parent → child → grandchild levels)
|
||||
- Want to showcase featured products/campaigns
|
||||
- Multiple segments (Men, Women, Kids, etc.)
|
||||
- Visual storytelling needed
|
||||
|
||||
**Use simple dropdown when:**
|
||||
- Small catalog (<10 categories)
|
||||
- Flat category structure (1-2 levels)
|
||||
- Text-only navigation sufficient
|
||||
- Minimalist design preference
|
||||
|
||||
**Common megamenu triggers:**
|
||||
- "Shop" (all categories)
|
||||
- "Men", "Women", "Kids" (segmented)
|
||||
- "New Arrivals" (curated)
|
||||
- "Sale" (promotional)
|
||||
|
||||
## Content Organization
|
||||
|
||||
**Backend Integration (CRITICAL):**
|
||||
|
||||
Fetch categories dynamically from ecommerce backend - never hardcode categories. Categories change frequently (new products, seasonal updates, inventory changes). Fetch from API on component mount or during SSR.
|
||||
|
||||
**Column structure (3-5 columns recommended):**
|
||||
|
||||
**Column 1-3: Category columns**
|
||||
- Parent category header (bold, non-clickable or clickable to "View All")
|
||||
- Child categories below (clickable links)
|
||||
- 5-10 links per column maximum
|
||||
- Group related subcategories
|
||||
|
||||
**Example:**
|
||||
|
||||
```plaintext
|
||||
Electronics (header)
|
||||
Laptops
|
||||
Desktops
|
||||
Monitors
|
||||
Accessories
|
||||
View All Electronics
|
||||
```
|
||||
|
||||
**Column 4-5: Promotional/Featured**
|
||||
- Product image card (1-2 featured products)
|
||||
- Campaign banner ("Summer Sale", "New Arrivals")
|
||||
- "Shop the Look" curated sets
|
||||
- Seasonal promotions
|
||||
|
||||
**Content limits:**
|
||||
|
||||
- Max 5 columns (avoid overcrowding)
|
||||
- Max 10 links per column
|
||||
- 1-2 promotional images maximum
|
||||
- Keep height reasonable (<600px)
|
||||
|
||||
## Layout Patterns
|
||||
|
||||
### ⚠️ CRITICAL: Megamenu Positioning (Common Mistake)
|
||||
|
||||
**Common positioning errors that MUST be avoided:**
|
||||
|
||||
❌ **Mistake 1: Navbar doesn't have `position: relative`**
|
||||
- Without positioning context on navbar, megamenu won't position correctly
|
||||
- Megamenu will position relative to document body instead of navbar
|
||||
|
||||
❌ **Mistake 2: Megamenu positioned relative to trigger button**
|
||||
- Causes megamenu to appear offset, not aligned to left edge
|
||||
- Megamenu won't span full width of navbar
|
||||
- Different trigger positions cause inconsistent megamenu placement
|
||||
|
||||
❌ **Mistake 3: Megamenu doesn't span full width**
|
||||
- Using `width: auto` or no width constraint
|
||||
- Missing `left: 0` and `right: 0` properties
|
||||
- Results in narrow dropdown instead of full-width panel
|
||||
|
||||
---
|
||||
|
||||
**REQUIRED positioning pattern:**
|
||||
|
||||
**Visual structure:**
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ NAVBAR (position: relative) │
|
||||
│ [Logo] [Shop ▼] [Men] [Women] [Cart] │
|
||||
└─────────────────────────────────────────────────┘
|
||||
┌───────────────────────────────────────────────┐
|
||||
│ MEGAMENU (absolute, left: 0, full width) │
|
||||
│ ┌─────────────────────────────────────────┐ │
|
||||
│ │ Container (centered content) │ │
|
||||
│ │ [Col1] [Col2] [Col3] [Promo] │ │
|
||||
│ └─────────────────────────────────────────┘ │
|
||||
└───────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Required structure:**
|
||||
|
||||
1. **Navbar container**
|
||||
- MUST have `position: relative`
|
||||
- Creates positioning context for megamenu
|
||||
- Contains both trigger button and megamenu dropdown
|
||||
|
||||
2. **Megamenu dropdown**
|
||||
- MUST have `position: absolute`
|
||||
- MUST have `left: 0` (aligns to left edge of navbar)
|
||||
- MUST have `right: 0` OR `width: 100%` (spans full navbar width)
|
||||
- MUST have `top: 100%` (positioned directly below navbar)
|
||||
- Should have appropriate `z-index` (above content, below modals)
|
||||
|
||||
3. **Content wrapper (inside megamenu)**
|
||||
- Use constrained width container (e.g., `max-width`, `container`)
|
||||
- Center content with `margin: 0 auto`
|
||||
- Contains grid/columns for megamenu content
|
||||
|
||||
**Why this pattern is mandatory:**
|
||||
- Navbar `position: relative` creates positioning context
|
||||
- Megamenu `absolute` + `left: 0` + full width ensures consistent, full-width layout
|
||||
- Positioning relative to navbar (not trigger) prevents offset issues
|
||||
- Inner container centers content while maintaining full-width background
|
||||
|
||||
---
|
||||
|
||||
### Other Layout Considerations
|
||||
|
||||
- Positioned below navbar (no gap)
|
||||
- White/light background, boxed padding
|
||||
- Shadow or border for depth
|
||||
- High z-index (above page content, below modals)
|
||||
|
||||
**Column layout:**
|
||||
- Equal-width columns or flexible grid
|
||||
- Adequate spacing (24-32px between columns)
|
||||
- Left-aligned text in category columns
|
||||
- Right column(s) for promotional content
|
||||
- Responsive: Stack columns on tablet if needed
|
||||
|
||||
**Promotional images:**
|
||||
- Right-aligned (1-2 columns)
|
||||
- Aspect ratio: 2:3 or square
|
||||
- Product images or lifestyle photography
|
||||
- Clickable to product/category page
|
||||
- Include caption or CTA ("Shop Now")
|
||||
|
||||
## Trigger Behavior
|
||||
|
||||
**Desktop hover (recommended):**
|
||||
- Megamenu opens on trigger hover
|
||||
- **CRITICAL: Megamenu MUST stay open while hovering over the dropdown content**
|
||||
- Stays open while hovering trigger OR dropdown area
|
||||
- Closes only when mouse leaves both trigger and dropdown areas
|
||||
- Debounce close (200-300ms delay) to prevent accidental closure
|
||||
- Smooth fade-in/out transition (200-300ms)
|
||||
|
||||
**Why this is critical:**
|
||||
- If dropdown closes when moving from trigger to content, users can't access links
|
||||
- Frustrating UX - users can't interact with megamenu items
|
||||
- Common mistake: Only listening for hover on trigger, not on dropdown
|
||||
|
||||
**Desktop click (alternative):**
|
||||
- Click trigger to toggle open/close
|
||||
- Click outside to close
|
||||
- Better for touch-enabled laptops
|
||||
- Less accidental openings
|
||||
|
||||
**Hover flickering prevention:**
|
||||
- No gap between navbar and dropdown
|
||||
- Dropdown should slightly overlap navbar
|
||||
- Debounce close delay prevents flickering
|
||||
|
||||
## Mobile Alternative
|
||||
|
||||
**Do NOT use megamenu on mobile:**
|
||||
- Too large for mobile screens
|
||||
- Hard to navigate multi-column layout
|
||||
- Poor touch experience
|
||||
|
||||
**Mobile alternative (hamburger menu):**
|
||||
- Hamburger icon opens slide-in drawer
|
||||
- Vertical accordion for categories
|
||||
- Parent category expands to show children
|
||||
- Simple, scrollable list
|
||||
- See navbar.md for mobile navigation patterns
|
||||
|
||||
**Breakpoint:**
|
||||
- Megamenu: Desktop only (>1024px)
|
||||
- Hamburger: Tablet and mobile (<1024px)
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
- [ ] Triggered from navbar items ("Shop", segments)
|
||||
- [ ] **CRITICAL: Navbar container has `position: relative` (creates positioning context)**
|
||||
- [ ] **CRITICAL: Megamenu has `position: absolute` with `left: 0` (NOT positioned relative to trigger button)**
|
||||
- [ ] **CRITICAL: Megamenu spans full width (`right: 0` or `w-full`, NOT just `w-auto`)**
|
||||
- [ ] **CRITICAL: Megamenu positioned at `top: 100%` or `top-full` (directly below navbar)**
|
||||
- [ ] Full-width dropdown below navbar, spans entire navbar width
|
||||
- [ ] 3-5 columns for organization
|
||||
- [ ] Category hierarchy (parent → children links)
|
||||
- [ ] Optional promotional images (1-2)
|
||||
- [ ] **CRITICAL: Megamenu stays open when hovering over dropdown content (not just trigger)**
|
||||
- [ ] Hover trigger with debounced close (200-300ms)
|
||||
- [ ] Smooth fade-in/out transition
|
||||
- [ ] No flickering (no gap between navbar and dropdown)
|
||||
- [ ] Mobile: Use hamburger menu, NOT megamenu
|
||||
- [ ] Keyboard accessible (Tab through links, Escape closes)
|
||||
- [ ] `role="navigation"` on dropdown panel
|
||||
- [ ] ARIA labels on trigger buttons
|
||||
- [ ] Screen reader friendly (announce expand/collapse)
|
||||
- [ ] Max 10 links per column
|
||||
- [ ] Max 5 columns total
|
||||
- [ ] Fetched dynamically from backend (don't hardcode categories)
|
||||
@@ -0,0 +1,397 @@
|
||||
# Navbar Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Decision: Simple Dropdown vs Megamenu](#decision-simple-dropdown-vs-megamenu)
|
||||
- [Key Ecommerce Patterns](#key-ecommerce-patterns)
|
||||
- [Layout Structure](#layout-structure)
|
||||
- [Accessibility Essentials](#accessibility-essentials)
|
||||
- [Common Ecommerce Mistakes](#common-ecommerce-mistakes)
|
||||
- [Backend Integration](#backend-integration)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Primary navigation for ecommerce storefronts. Desktop: horizontal menu with category links. Mobile: hamburger drawer with accordion subcategories.
|
||||
|
||||
### ⚠️ CRITICAL: NEVER Hardcode Categories
|
||||
|
||||
**ALWAYS fetch categories dynamically from the backend. NEVER hardcode static category arrays.**
|
||||
|
||||
❌ **WRONG - DO NOT DO THIS:**
|
||||
```typescript
|
||||
// WRONG - Static hardcoded categories
|
||||
const categories = [
|
||||
{ name: "Women", href: "/categories/women" },
|
||||
{ name: "Men", href: "/categories/men" },
|
||||
{ name: "Accessories", href: "/categories/accessories" }
|
||||
]
|
||||
```
|
||||
|
||||
✅ **CORRECT - Fetch from backend:**
|
||||
```typescript
|
||||
// CORRECT - Fetch categories dynamically
|
||||
const [categories, setCategories] = useState([])
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`${apiUrl}/store/product-categories`)
|
||||
.then(res => res.json())
|
||||
.then(data => setCategories(data.product_categories))
|
||||
}, [])
|
||||
```
|
||||
|
||||
**Why this matters:**
|
||||
- Categories change frequently (new categories, renamed, reordered)
|
||||
- Hardcoded categories become outdated immediately
|
||||
- Requires code changes every time categories change
|
||||
- Cannot scale to stores with dynamic catalogs
|
||||
- Defeats the purpose of headless commerce
|
||||
|
||||
### Key Requirements
|
||||
|
||||
- Desktop: Horizontal category links, cart/account/search right-aligned
|
||||
- Mobile: Hamburger drawer, cart stays visible in header (not hidden in drawer)
|
||||
- **CRITICAL: Fetch categories from backend dynamically (NEVER hardcode static arrays)**
|
||||
- Sticky: Recommended for easy cart access while browsing
|
||||
- Real-time updates: Cart count, login state, category changes
|
||||
|
||||
## Decision: Simple Dropdown vs Megamenu
|
||||
|
||||
**Use Simple Dropdown when:**
|
||||
- <10 top-level categories
|
||||
- Flat or shallow hierarchy (1-2 levels deep)
|
||||
- Minimal subcategories per parent
|
||||
- Focused/specialized product catalog
|
||||
|
||||
**Use Megamenu when:**
|
||||
- 10+ top-level categories
|
||||
- Deep hierarchy (3+ levels)
|
||||
- Need to showcase featured products in navigation
|
||||
- Complex product catalog
|
||||
- Fashion, electronics, or large inventory
|
||||
|
||||
**Mobile**: Always use drawer with accordion pattern, never megamenu on mobile.
|
||||
|
||||
See [megamenu.md](megamenu.md) for megamenu implementation details.
|
||||
|
||||
## Key Ecommerce Patterns
|
||||
|
||||
### Cart Indicator (CRITICAL)
|
||||
|
||||
**Always visible on both desktop and mobile:**
|
||||
- Desktop: Top-right, cart icon + count badge
|
||||
- Mobile: Top-right in header (NOT hidden in hamburger drawer)
|
||||
- This is non-negotiable - users expect cart always accessible
|
||||
|
||||
**Badge display:**
|
||||
- Shows item count (NOT price - confusing when variants change)
|
||||
- Only visible when cart has items (count > 0)
|
||||
- Show actual count up to 99, then "99+"
|
||||
- Position: Top-right corner of cart icon
|
||||
- ARIA label: `aria-label="Shopping cart with 3 items"`
|
||||
|
||||
**Real-time updates:**
|
||||
- Update count immediately when items added (optimistic UI)
|
||||
- No page refresh required
|
||||
- Sync with backend cart state
|
||||
- Handle errors gracefully (restore count if add fails)
|
||||
|
||||
**Click behavior:**
|
||||
- Option 1: Navigate to cart page
|
||||
- Option 2: Open cart popup/drawer (see cart-popup.md)
|
||||
- Choice depends on store type (see cart-popup.md for decision criteria)
|
||||
|
||||
✅ **CORRECT:**
|
||||
- Cart icon visible in mobile header
|
||||
- Badge shows count (not price)
|
||||
- Updates in real-time without page refresh
|
||||
- 44x44px touch target
|
||||
- Links to cart or opens cart popup
|
||||
|
||||
❌ **WRONG:**
|
||||
- Hiding cart in mobile hamburger drawer (users can't find it)
|
||||
- Showing price in badge (€25.99) instead of count
|
||||
- Cart count doesn't update until page refresh
|
||||
- No visual feedback when items added
|
||||
|
||||
### Category Navigation
|
||||
|
||||
**CRITICAL: Fetch dynamically from backend (NEVER hardcode):**
|
||||
|
||||
❌ **WRONG - These are all incorrect approaches:**
|
||||
```typescript
|
||||
// WRONG - Hardcoded array
|
||||
const categories = ["Women", "Men", "Kids", "Accessories"]
|
||||
|
||||
// WRONG - Static object array
|
||||
const categories = [
|
||||
{ id: 1, name: "Women", slug: "women" },
|
||||
{ id: 2, name: "Men", slug: "men" }
|
||||
]
|
||||
|
||||
// WRONG - Importing static data
|
||||
import { categories } from "./categories.ts"
|
||||
```
|
||||
|
||||
✅ **CORRECT - Fetch from backend API:**
|
||||
- Medusa: Use SDK category list method (verify exact method with docs/MCP)
|
||||
- Other backends: Call categories endpoint (check API documentation)
|
||||
- Fetch on component mount or during server-side rendering
|
||||
|
||||
**Why dynamic fetching is mandatory:**
|
||||
- Store owners add/remove/rename categories frequently
|
||||
- Category order and hierarchy changes
|
||||
- Multi-language stores need translated category names
|
||||
- Featured categories rotate (seasonal, promotions)
|
||||
- Hardcoded values require developer intervention for simple changes
|
||||
|
||||
**Caching strategy:**
|
||||
- Cache categories (revalidate on interval or manual trigger)
|
||||
- Use SWR, TanStack Query, or framework-level caching
|
||||
- Revalidate every 5-10 minutes or on page navigation
|
||||
- Update immediately when backend categories change
|
||||
|
||||
**Organization:**
|
||||
- 4-7 top-level categories ideal (max 10 on desktop)
|
||||
- Order comes from backend (respects admin's ordering)
|
||||
- Keep "Sale" or "New Arrivals" prominent if backend provides it
|
||||
- Maximum 2 levels in simple dropdown (category → subcategory)
|
||||
- Deeper hierarchies: Use megamenu or separate category pages
|
||||
|
||||
**Desktop behavior:**
|
||||
- Horizontal links with hover dropdowns for subcategories
|
||||
- Slight hover delay to prevent accidental triggers
|
||||
- Click parent to navigate to category page
|
||||
- Click child to navigate to subcategory
|
||||
|
||||
**Mobile behavior:**
|
||||
- All categories in hamburger drawer
|
||||
- Accordion pattern for subcategories (expand/collapse)
|
||||
- Close drawer on category click (except expanding accordion)
|
||||
- Scrollable drawer if categories exceed viewport height
|
||||
|
||||
✅ **CORRECT:**
|
||||
- Categories fetched from backend API on mount
|
||||
- Cache with revalidation strategy
|
||||
- Respects backend ordering and hierarchy
|
||||
- 4-7 top-level items on desktop (based on what backend returns)
|
||||
- Accordion for mobile subcategories
|
||||
- Consistent ordering across devices
|
||||
|
||||
❌ **WRONG:**
|
||||
- Hardcoded category array in component (NEVER DO THIS)
|
||||
- Static categories imported from file (NEVER DO THIS)
|
||||
- No cache invalidation (stale categories)
|
||||
- Too many top-level items (>10, overwhelming)
|
||||
- Different category order on desktop vs mobile
|
||||
- Categories don't update when backend changes
|
||||
|
||||
### User Account Indicator
|
||||
|
||||
**Two states based on authentication:**
|
||||
|
||||
**Logged out:**
|
||||
- Desktop: "Sign In" or "Log In" text + user icon
|
||||
- Mobile: User icon only
|
||||
- Click navigates to login page
|
||||
- Clear call-to-action
|
||||
|
||||
**Logged in:**
|
||||
- Desktop: User name, initials, or email + dropdown
|
||||
- Mobile: User name/initials or icon → account page
|
||||
- Dropdown menu (desktop): My Account, Orders, Wishlist, Sign Out
|
||||
- Fetch current user from backend authentication state
|
||||
|
||||
**Authentication state management:**
|
||||
- Check auth state from backend (not just localStorage)
|
||||
- Update immediately on login/logout events
|
||||
- Handle session expiration gracefully
|
||||
- Sync across tabs if possible
|
||||
|
||||
✅ **CORRECT:**
|
||||
- Shows "Sign In" when logged out
|
||||
- Shows user identifier when logged in
|
||||
- Dropdown with account actions
|
||||
- Checks backend auth state (not just client state)
|
||||
|
||||
❌ **WRONG:**
|
||||
- No indication of login state
|
||||
- Relies solely on localStorage (can be stale)
|
||||
- No dropdown for account actions when logged in
|
||||
- Missing logout option
|
||||
|
||||
### Mobile Navigation Pattern
|
||||
|
||||
**Hamburger drawer:**
|
||||
- Trigger: Hamburger icon (top-left)
|
||||
- Drawer: Slides from left, 80-85% width, full height, scrollable
|
||||
- Backdrop: Semi-transparent overlay, click to close
|
||||
- Content: All categories with accordion subcategories
|
||||
|
||||
**CRITICAL: Keep cart in header:**
|
||||
- Cart icon stays in mobile header (top-right)
|
||||
- Don't hide cart inside drawer
|
||||
- Users expect cart always accessible
|
||||
- Same for search icon if using icon-only search
|
||||
|
||||
**Account in drawer:**
|
||||
- Logged out: "Sign In" link in drawer header or top of menu
|
||||
- Logged in: User name/initials in drawer header with link to account
|
||||
|
||||
**Close behavior:**
|
||||
- Close button (X) in drawer header
|
||||
- Click backdrop overlay
|
||||
- Navigate to category (drawer closes)
|
||||
- Escape key
|
||||
|
||||
✅ **CORRECT:**
|
||||
- Cart stays in mobile header (visible)
|
||||
- Hamburger opens drawer from left
|
||||
- Backdrop overlay dims background
|
||||
- Close on navigation or backdrop click
|
||||
- Scrollable drawer for long menus
|
||||
|
||||
❌ **WRONG:**
|
||||
- Cart hidden inside hamburger drawer (cardinal sin)
|
||||
- Full-screen drawer (no backdrop)
|
||||
- Drawer doesn't close on navigation
|
||||
- Not scrollable (categories cut off)
|
||||
|
||||
### Bottom Navigation (Alternative for Mobile)
|
||||
|
||||
**When to use:**
|
||||
- Store has 3-5 key sections (Home, Browse, Cart, Account, Search)
|
||||
- App-like experience desired
|
||||
- Frequent switching between sections
|
||||
- Not suitable for complex category hierarchies
|
||||
|
||||
**Pattern:**
|
||||
- Fixed bar at bottom of screen (mobile only)
|
||||
- Icon + label for each section
|
||||
- Highlight active section
|
||||
- 5 items maximum
|
||||
- Direct navigation, no dropdowns
|
||||
|
||||
## Layout Structure
|
||||
|
||||
**Desktop:**
|
||||
- Left: Logo → Homepage
|
||||
- Center: Category links (horizontal)
|
||||
- Right: Search, Account, Cart
|
||||
|
||||
**Mobile:**
|
||||
- Left: Hamburger
|
||||
- Center: Logo
|
||||
- Right: Cart (+ Search icon optional)
|
||||
|
||||
**Sticky recommended:**
|
||||
- Keeps cart/account accessible while scrolling
|
||||
- Use `position: sticky` or `position: fixed`
|
||||
- Solid background color (hide scrolling content)
|
||||
- Adequate z-index to stay above content
|
||||
|
||||
## Accessibility Essentials
|
||||
|
||||
**Ecommerce-specific ARIA:**
|
||||
- Cart count: `aria-live="polite"` to announce changes (e.g., "3 items in cart")
|
||||
- Mobile drawer: `role="dialog"`, `aria-modal="true"`
|
||||
- Hamburger button: `aria-label="Open navigation menu"`, `aria-expanded="false"`
|
||||
- Active page: `aria-current="page"` on current category link
|
||||
- Dropdown indicators: `aria-expanded`, `aria-controls` for megamenu relationships
|
||||
|
||||
**Keyboard navigation:**
|
||||
- Tab through all links/buttons
|
||||
- Enter/Space to activate
|
||||
- Escape to close mobile menu or dropdowns
|
||||
- Visible focus indicators (outline/ring)
|
||||
|
||||
**Generic accessibility applies:**
|
||||
- Semantic HTML (`<header>`, `<nav>`)
|
||||
- Icon buttons need ARIA labels
|
||||
- 4.5:1 color contrast minimum
|
||||
- 44x44px touch targets on mobile
|
||||
|
||||
## Common Ecommerce Mistakes
|
||||
|
||||
❌ **CRITICAL: Hardcoded static categories** - NEVER create static category arrays like `const categories = ["Women", "Men"]` or import from static files. ALWAYS fetch from backend API. Categories change constantly - new categories added, names changed, ordering updated. Hardcoded categories require developer intervention for simple changes and defeat the purpose of dynamic commerce platforms. This is the #1 most common mistake.
|
||||
|
||||
❌ **Hiding cart in mobile drawer** - Users expect cart always visible. Keep cart icon in header (top-right), not hidden inside hamburger menu.
|
||||
|
||||
❌ **No real-time cart updates** - Update count immediately when items added (optimistic UI). Don't require page refresh.
|
||||
|
||||
❌ **Showing price in cart badge** - Show item count (number), not total price. Price display confuses when variants have different quantities.
|
||||
|
||||
❌ **No cache invalidation** - Categories become stale when backend changes. Revalidate periodically (5-10 min) or on manual trigger.
|
||||
|
||||
❌ **Hover-only dropdowns on mobile** - Use click/tap interactions. Hover doesn't work on touch devices.
|
||||
|
||||
❌ **Desktop navigation on mobile** - Use hamburger drawer pattern, not horizontal menu that doesn't fit.
|
||||
|
||||
❌ **Inconsistent category order** - Same order on desktop and mobile for consistency. Respect backend's category ordering.
|
||||
|
||||
## Backend Integration
|
||||
|
||||
### Category Fetching (CRITICAL - NEVER Hardcode)
|
||||
|
||||
**Implementation patterns:**
|
||||
|
||||
**Client-side fetching:**
|
||||
- Fetch categories in useEffect on mount
|
||||
- Store in state (use appropriate types for Medusa: StoreProductCategory)
|
||||
- Handle loading and error states
|
||||
- Map categories to navigation links
|
||||
- Use category.id as key, category.handle for URL, category.name for display
|
||||
|
||||
**With caching (RECOMMENDED):**
|
||||
- Use TanStack Query with queryKey ['categories']
|
||||
- Set staleTime: 5-10 minutes (categories rarely change)
|
||||
- Automatic loading/error states
|
||||
- Request deduplication if multiple components need categories
|
||||
|
||||
**Server-side fetching:**
|
||||
- Fetch in server component or load function
|
||||
- No loading state needed (rendered on server)
|
||||
- Better for SEO
|
||||
|
||||
**Cart state synchronization pattern:**
|
||||
- Subscribe to global cart state (Context)
|
||||
- Update navbar cart count when cart changes
|
||||
- Handle optimistic updates (show new count immediately on add to cart)
|
||||
- Sync with backend on events or interval
|
||||
|
||||
**Authentication state pattern:**
|
||||
- Check auth state from backend on mount
|
||||
- Listen for login/logout events
|
||||
- Update account indicator immediately
|
||||
- Handle session expiration gracefully
|
||||
|
||||
**Category update triggers:**
|
||||
- On page load/navigation
|
||||
- On manual refresh trigger
|
||||
- On revalidation interval (5-10 minutes)
|
||||
- After admin updates categories (webhook or polling)
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential navbar features:**
|
||||
|
||||
- [ ] **CRITICAL: Categories fetched dynamically from backend API (NOT hardcoded arrays)**
|
||||
- [ ] **CRITICAL: No static category imports or hardcoded category lists**
|
||||
- [ ] Desktop: Horizontal category links
|
||||
- [ ] Mobile: Hamburger drawer with accordion
|
||||
- [ ] Cart icon visible on both desktop and mobile header (NOT hidden in drawer)
|
||||
- [ ] Cart badge shows item count (not price)
|
||||
- [ ] Cart count updates in real-time
|
||||
- [ ] Categories use backend ordering (not manual ordering)
|
||||
- [ ] Account indicator shows login state
|
||||
- [ ] Logo links to homepage
|
||||
- [ ] 4-7 top-level categories displayed (max 10)
|
||||
- [ ] Mobile drawer closes on navigation
|
||||
- [ ] Sticky navigation (recommended)
|
||||
- [ ] 44x44px minimum touch targets
|
||||
- [ ] ARIA labels on icon buttons
|
||||
- [ ] `aria-live` on cart count for screen readers
|
||||
- [ ] Keyboard accessible with visible focus states
|
||||
- [ ] Categories cached with revalidation strategy (5-10 min)
|
||||
- [ ] Error handling for failed category fetch
|
||||
@@ -0,0 +1,221 @@
|
||||
# Popups Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [When to Use Popups](#when-to-use-popups)
|
||||
- [Ecommerce Popup Types](#ecommerce-popup-types)
|
||||
- [Timing and Triggers](#timing-and-triggers)
|
||||
- [Frequency Management](#frequency-management)
|
||||
- [Mobile Considerations](#mobile-considerations)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Popups (modals/overlays) appear over main content to capture attention for specific actions: newsletter signups, promotional offers, exit-intent offers.
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build modals with close buttons and backdrop overlays. This focuses on ecommerce popup patterns.
|
||||
|
||||
**Critical balance**: Effective for conversions when used sparingly, intrusive and annoying when overused. Timing and frequency are critical for ecommerce.
|
||||
|
||||
## When to Use Popups
|
||||
|
||||
**Use popups when:**
|
||||
|
||||
- Offering significant value (10-20% first-purchase discount, free shipping)
|
||||
- Time-sensitive promotions (flash sale ending soon)
|
||||
- Exit-intent to recover abandoning visitors (last chance offer)
|
||||
- First-time visitor welcome (one-time only)
|
||||
- Important announcements (shipping delays, policy changes)
|
||||
|
||||
**Don't use popups for:**
|
||||
|
||||
- Every page visit (extremely annoying)
|
||||
- Multiple popups per session
|
||||
- Immediate page load (users haven't seen site yet)
|
||||
- Mobile users (especially full-screen takeovers - very disruptive)
|
||||
- Users who already signed up or dismissed
|
||||
|
||||
**Consider alternatives:**
|
||||
|
||||
- Top banner: Less intrusive, always visible, good for ongoing promotions
|
||||
- Inline forms: Homepage or footer newsletter signup, non-blocking
|
||||
- Slide-in (corner): From bottom-right, less disruptive than center popup
|
||||
- Post-purchase: Ask for email after successful order (high conversion)
|
||||
|
||||
**Popups are best when:** Need immediate attention, high-value offer justifies interruption, exit-intent (last chance).
|
||||
|
||||
## Ecommerce Popup Types
|
||||
|
||||
### 1. First-Purchase Discount
|
||||
|
||||
**Purpose**: Convert first-time visitors with discount incentive.
|
||||
|
||||
**Content:**
|
||||
- Headline: "Welcome! Get 10% Off Your First Order"
|
||||
- Email input
|
||||
- Discount code or automatic application
|
||||
- Subscribe button: "Get My Discount"
|
||||
|
||||
**Timing**: After 30-60 seconds on site OR after viewing 2-3 products (engagement signal).
|
||||
|
||||
**Frequency**: Once per user (cookie/localStorage). Don't show to returning customers.
|
||||
|
||||
### 2. Newsletter Signup
|
||||
|
||||
**Purpose**: Grow email list for marketing.
|
||||
|
||||
**Content:**
|
||||
- Value proposition: "Get exclusive deals and early access"
|
||||
- Email input
|
||||
- Subscribe button
|
||||
- Optional: First-purchase discount incentive (10-15% off)
|
||||
|
||||
**Timing**: After 50% scroll OR 60 seconds on site.
|
||||
|
||||
**Frequency**: Once per session. If dismissed, don't show for 30 days.
|
||||
|
||||
### 3. Exit-Intent Popup
|
||||
|
||||
**Purpose**: Recover abandoning visitors with last-chance offer.
|
||||
|
||||
**Trigger**: Mouse moves toward browser close/back button (desktop only).
|
||||
|
||||
**Content:**
|
||||
- Urgency: "Wait! Don't Miss Out"
|
||||
- Offer: "Take 10% Off Your Order" or "Free Shipping Today Only"
|
||||
- Email capture (optional): "Send me the code"
|
||||
- CTA: "Claim Offer" or "Continue Shopping"
|
||||
|
||||
**Best for**: Cart abandoners, product page exits, first-time visitors.
|
||||
|
||||
**Frequency**: Once per session. Don't show if user already added to cart or on checkout.
|
||||
|
||||
### 4. Cart Abandonment Reminder
|
||||
|
||||
**Purpose**: Remind user of items in cart before leaving.
|
||||
|
||||
**Trigger**: Exit-intent when cart has items but user navigating away.
|
||||
|
||||
**Content:**
|
||||
- "Your Cart is Waiting"
|
||||
- Show cart summary (items, total)
|
||||
- CTA: "Complete Your Order" or "View Cart"
|
||||
- Optional incentive: "Complete in 10 minutes for free shipping"
|
||||
|
||||
**Frequency**: Once per session with items in cart.
|
||||
|
||||
### 5. Promotional Announcement
|
||||
|
||||
**Purpose**: Announce sales, new arrivals, or site-wide events.
|
||||
|
||||
**Content:**
|
||||
- Headline: "Flash Sale: 40% Off Everything"
|
||||
- Subtext: "Ends in 3 hours"
|
||||
- CTA: "Shop Now"
|
||||
|
||||
**Timing**: Immediate on page load (if major event), OR after 30 seconds.
|
||||
|
||||
**Frequency**: Once per day during promotion period.
|
||||
|
||||
## Timing and Triggers
|
||||
|
||||
**Time-based:**
|
||||
- 30-60 seconds after page load (enough time to browse)
|
||||
- Never immediate (0 seconds) - users need to see site first
|
||||
|
||||
**Engagement-based:**
|
||||
- After 50% scroll (shows interest)
|
||||
- After viewing 2-3 products (qualified visitor)
|
||||
- After adding to cart (exit-intent only)
|
||||
|
||||
**Exit-intent:**
|
||||
- Mouse moves toward close/back button (desktop)
|
||||
- Scroll-up toward address bar (mobile - less reliable)
|
||||
- Only trigger once per session
|
||||
- Don't trigger on checkout pages (interrupts purchase)
|
||||
|
||||
**Page-specific:**
|
||||
- Homepage: Welcome/discount popup
|
||||
- Product pages: Exit-intent with product-specific offer
|
||||
- Cart page: Don't use popups (already engaged)
|
||||
- Checkout: Never use popups (critical flow)
|
||||
|
||||
## Frequency Management
|
||||
|
||||
**Critical for UX**: Don't show same popup repeatedly to same user.
|
||||
|
||||
**Implementation:**
|
||||
|
||||
1. **Cookie/localStorage tracking**: Store dismissal/signup with timestamp
|
||||
2. **Respect dismissals**: If user closes popup, don't show for 30 days
|
||||
3. **Signed-up users**: Never show newsletter popup again
|
||||
4. **Session limits**: Max 1 popup per session
|
||||
5. **Time cooldown**: If dismissed, wait 30 days before showing again
|
||||
|
||||
**Example tracking:**
|
||||
```javascript
|
||||
// On popup dismiss
|
||||
localStorage.setItem('popup_dismissed', Date.now())
|
||||
localStorage.setItem('popup_type', 'welcome_discount')
|
||||
|
||||
// Before showing popup
|
||||
const dismissedTime = localStorage.getItem('popup_dismissed')
|
||||
const daysSince = (Date.now() - dismissedTime) / (1000 * 60 * 60 * 24)
|
||||
if (daysSince < 30) {
|
||||
// Don't show popup
|
||||
}
|
||||
```
|
||||
|
||||
**Progressive disclosure:**
|
||||
- Session 1: Welcome discount popup
|
||||
- Session 2+: Exit-intent only (if applicable)
|
||||
- Never stack multiple popups
|
||||
|
||||
## Mobile Considerations
|
||||
|
||||
**Mobile popups are MORE intrusive:**
|
||||
- Smaller screen = popup takes more space
|
||||
- Harder to close (small X button)
|
||||
- Disrupts mobile browsing flow
|
||||
- Can hurt mobile SEO (Google penalty for intrusive interstitials)
|
||||
|
||||
**Mobile best practices:**
|
||||
|
||||
1. **Use sparingly**: Consider top banner or inline forms instead
|
||||
2. **Make easily dismissable**: Large close button (44x44px), tap outside to close
|
||||
3. **Delay longer**: 60+ seconds instead of 30 seconds
|
||||
4. **Smaller size**: 90% width max, not full-screen
|
||||
5. **Exit-intent**: Less reliable on mobile, avoid
|
||||
6. **Google penalty**: Avoid full-screen popups on mobile (hurts rankings)
|
||||
|
||||
**Mobile alternative**: Sticky bottom bar (less intrusive)
|
||||
- "Get 10% Off - Sign Up" with email input
|
||||
- Always visible but doesn't block content
|
||||
- Better mobile UX than popup
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Clear value proposition (discount, benefit)
|
||||
- [ ] Single focused CTA
|
||||
- [ ] Easy to close (X button, backdrop click, Escape key)
|
||||
- [ ] Delayed timing (30-60s, not immediate)
|
||||
- [ ] Frequency management (localStorage/cookie tracking)
|
||||
- [ ] Respect dismissals (30-day cooldown)
|
||||
- [ ] Never show to signed-up users
|
||||
- [ ] Max 1 popup per session
|
||||
- [ ] Exit-intent for cart abandoners (desktop only)
|
||||
- [ ] Don't show on checkout pages
|
||||
- [ ] Mobile: Use sparingly, consider alternatives
|
||||
- [ ] Mobile: Large close button (44x44px)
|
||||
- [ ] Mobile: Not full-screen (90% width max)
|
||||
- [ ] Email validation before submit
|
||||
- [ ] Loading state on submit
|
||||
- [ ] Success message or redirect
|
||||
- [ ] Keyboard accessible (Tab, Escape, Enter)
|
||||
- [ ] `role="dialog"` and `aria-modal="true"`
|
||||
- [ ] Focus trap (keep focus within popup)
|
||||
- [ ] ARIA label on close button
|
||||
- [ ] Screen reader announcements on open
|
||||
@@ -0,0 +1,125 @@
|
||||
# Product Card Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Price Display (Ecommerce-Specific)](#price-display-ecommerce-specific)
|
||||
- [Action Buttons and Variant Handling](#action-buttons-and-variant-handling)
|
||||
- [Badges and Labels](#badges-and-labels)
|
||||
- [Mobile Considerations](#mobile-considerations)
|
||||
- [Ecommerce Checklist](#ecommerce-checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Product cards display products in grids (product listings, search results, related products). Key ecommerce considerations: clear pricing, quick add-to-cart, and stock indicators.
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build cards with images, titles, and buttons. This guide focuses on ecommerce-specific patterns.
|
||||
|
||||
### Key Ecommerce Requirements
|
||||
|
||||
- Clear, prominent pricing (including sale prices)
|
||||
- Variant handling for add-to-cart
|
||||
- Stock status indicators
|
||||
- Sale/New/Out of Stock badges
|
||||
- Responsive grid (1 col mobile, 2-3 tablet, 3-4 desktop)
|
||||
- Fast image loading (lazy load, optimized)
|
||||
|
||||
## Price Display (Ecommerce-Specific)
|
||||
|
||||
### Regular vs Sale Pricing
|
||||
|
||||
**Sale price display:**
|
||||
- Sale price: Larger, bold, red or accent color
|
||||
- Original price: Smaller, struck through (~~$79.99~~), gray
|
||||
- Position sale price before original price
|
||||
- Optional: Show discount percentage badge (-20%)
|
||||
|
||||
**Format consistently:**
|
||||
- Always include currency symbol ($49.99)
|
||||
- Consistent decimals ($49.99 not $49.9 or $50)
|
||||
- For Medusa: Display prices as-is (no divide by 100)
|
||||
|
||||
### Price Range (Multiple Variants)
|
||||
|
||||
**When variants have different prices:**
|
||||
- Show "From $49" or "$49 - $79"
|
||||
- Makes it clear price varies by selection
|
||||
- Don't show range if all variants same price
|
||||
|
||||
## Action Buttons and Variant Handling
|
||||
|
||||
### Add to Cart with Variants (CRITICAL)
|
||||
|
||||
**Key challenge**: Products with variants require variant selection before adding to cart.
|
||||
|
||||
**Handling strategies:**
|
||||
|
||||
1. **Add first variant by default** - Click adds `product.variants[0]`. Fast for simple products (1-2 variants).
|
||||
2. **Redirect to product page** - Navigate to detail page for variant selection. Best for complex products (size + color + material).
|
||||
3. **Quick View modal** - Variant selector in modal. Good middle ground (desktop only).
|
||||
|
||||
**Decision:**
|
||||
- Simple products (1-2 variants): Add first variant
|
||||
- Fashion/apparel with sizes: Require size selection (redirect or Quick View)
|
||||
- Complex products (3+ variant types): Redirect to product page
|
||||
|
||||
**Button behavior:**
|
||||
- Loading state ("Adding..."), disable during loading
|
||||
- Optimistic UI update (cart count immediately)
|
||||
- Success feedback (toast, cart popup, or checkmark)
|
||||
- **Don't navigate away** (stay on listing page)
|
||||
- Handle errors (out of stock, API failure)
|
||||
|
||||
**Wishlist button (optional)**: Heart icon, top-right over image. Empty when not saved, filled (red) when saved. Refer to wishlist.md for more details.
|
||||
|
||||
## Badges and Labels
|
||||
|
||||
**Badge priority** (show max 1-2 per card):
|
||||
|
||||
1. **Out of Stock** (highest) - Gray/black overlay on image, disables add-to-cart
|
||||
2. **Sale/Discount** - "Sale" or "-20%", red/accent, top-left corner
|
||||
3. **New** - "New" for recent products, blue/green, top-left corner
|
||||
4. **Low Stock** (optional) - "Only 3 left", orange, creates urgency
|
||||
|
||||
**Display**: Top-left corner (except Out of Stock overlay), small but readable, high contrast.
|
||||
|
||||
## Mobile Considerations
|
||||
|
||||
### Grid Layout
|
||||
|
||||
**Mobile-specific adjustments:**
|
||||
- 2 columns maximum on mobile (never 3+)
|
||||
- Larger touch targets (44px minimum for buttons)
|
||||
- Always show "Add to Cart" button (no hover-only)
|
||||
- Simplified content (hide optional elements like brand)
|
||||
- Smaller images for performance (<400px wide)
|
||||
|
||||
### Touch Interactions
|
||||
|
||||
**No hover states on mobile:**
|
||||
- Don't hide actions behind hover
|
||||
- Always show primary button
|
||||
- Use tap states (active state) instead of hover
|
||||
|
||||
## Ecommerce Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Clear product image (optimized, lazy loaded)
|
||||
- [ ] Product title (truncated to 2 lines max)
|
||||
- [ ] Price prominently displayed
|
||||
- [ ] Sale price shown correctly (struck-through original price)
|
||||
- [ ] Currency symbol included
|
||||
- [ ] For Medusa: Price displayed as-is (not divided by 100)
|
||||
- [ ] Add to Cart button with loading state
|
||||
- [ ] Variant handling strategy (first variant, redirect, or Quick View)
|
||||
- [ ] Optimistic UI update (cart count immediately)
|
||||
- [ ] Success feedback (toast or cart popup)
|
||||
- [ ] Don't navigate away after adding to cart
|
||||
- [ ] Out of Stock badge (disables add-to-cart)
|
||||
- [ ] Sale badge when price reduced
|
||||
- [ ] Responsive grid (1 col mobile, 2-3 tablet, 3-4 desktop)
|
||||
- [ ] Touch-friendly on mobile (44px buttons)
|
||||
- [ ] Keyboard accessible (focus states, Enter to activate)
|
||||
- [ ] Descriptive alt text on images
|
||||
- [ ] Semantic HTML (`<article>` wrapper)
|
||||
@@ -0,0 +1,217 @@
|
||||
# Product Reviews Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Review Display Patterns](#review-display-patterns)
|
||||
- [Rating Summary and Distribution](#rating-summary-and-distribution)
|
||||
- [Sorting and Filtering](#sorting-and-filtering)
|
||||
- [Review Submission](#review-submission)
|
||||
- [Trust Signals](#trust-signals)
|
||||
- [SEO Integration](#seo-integration)
|
||||
|
||||
## Overview
|
||||
|
||||
Product reviews build trust and influence purchase decisions. Reviews with ratings convert 270% better than products without.
|
||||
|
||||
**Assumed knowledge**: Claude knows how to build forms and display lists. This guide focuses on ecommerce review patterns and trust signals.
|
||||
|
||||
### Key Requirements
|
||||
|
||||
- Star rating summary (1-5 stars) with distribution
|
||||
- Individual reviews with ratings, text, author, date
|
||||
- Sorting (Most Recent, Most Helpful, Highest/Lowest Rating)
|
||||
- Filtering by rating (5 stars only, 4+ stars)
|
||||
- Verified purchase badges
|
||||
- Helpful votes (upvote system)
|
||||
- Review submission form
|
||||
- Mobile-optimized
|
||||
|
||||
## Review Display Patterns
|
||||
|
||||
### Placement
|
||||
|
||||
**On product page:**
|
||||
- Below product details (after add-to-cart)
|
||||
- Before related products
|
||||
- Anchor link in product info: "★★★★★ (127 reviews)"
|
||||
|
||||
**Separate reviews page:**
|
||||
- Only for very large catalogs (500+ reviews)
|
||||
- Link: "View All Reviews"
|
||||
- Most stores show reviews inline on product page
|
||||
|
||||
## Rating Summary and Distribution
|
||||
|
||||
### Average Rating Display
|
||||
|
||||
**Show prominently:**
|
||||
- Average rating: "★★★★★ 4.5 out of 5"
|
||||
- Total review count: "Based on 127 reviews"
|
||||
- Large stars (24-32px)
|
||||
|
||||
### Rating Distribution (CRITICAL)
|
||||
|
||||
**Visual breakdown with clickable bars:**
|
||||
```
|
||||
5 ★ [████████████████████] 82 (65%)
|
||||
4 ★ [██████░░░░░░░░░░░░░░] 25 (20%)
|
||||
3 ★ [██░░░░░░░░░░░░░░░░░░] 10 (8%)
|
||||
2 ★ [█░░░░░░░░░░░░░░░░░░░] 5 (4%)
|
||||
1 ★ [█░░░░░░░░░░░░░░░░░░░] 5 (3%)
|
||||
```
|
||||
|
||||
**Make bars clickable:**
|
||||
- Click to filter reviews by rating
|
||||
- Shows only selected star ratings
|
||||
- "Show all" to reset filter
|
||||
|
||||
**Why distribution matters:**
|
||||
- Perfect 5.0 rating seems fake (customers trust 4.2-4.5 average)
|
||||
- Showing negative reviews builds trust
|
||||
- Distribution helps customers understand product quality
|
||||
|
||||
### No Reviews State
|
||||
|
||||
**When no reviews:**
|
||||
- "No reviews yet"
|
||||
- "Be the first to review this product"
|
||||
- "Write a Review" button prominent
|
||||
- Don't show 0 stars or empty rating
|
||||
|
||||
## Sorting and Filtering
|
||||
|
||||
### Sort Options (CRITICAL)
|
||||
|
||||
**Essential sorting:**
|
||||
- **Most Recent** (default) - shows latest feedback
|
||||
- **Most Helpful** (by upvotes) - surfaces best reviews
|
||||
- **Highest Rating** (5 stars first) - see positive feedback
|
||||
- **Lowest Rating** (1 star first) - see concerns
|
||||
|
||||
**Dropdown selector:**
|
||||
```
|
||||
Sort by: [Most Recent ▾]
|
||||
```
|
||||
|
||||
### Filter Options
|
||||
|
||||
**Filter by rating:**
|
||||
- All ratings (default)
|
||||
- 5 stars only
|
||||
- 4+ stars
|
||||
- 3 stars or less (see negative feedback)
|
||||
|
||||
**Filter by criteria:**
|
||||
- Verified purchases only (highest trust)
|
||||
- With photos only (visual proof)
|
||||
- Recent (last 30 days, 6 months)
|
||||
|
||||
**Show filtered count:**
|
||||
- "Showing 24 of 127 reviews"
|
||||
|
||||
## Review Submission
|
||||
|
||||
### Review Form Fields
|
||||
|
||||
**Required:**
|
||||
- Star rating (1-5 stars selector)
|
||||
- Review text (textarea, 50-500 characters)
|
||||
- Reviewer name (if not logged in)
|
||||
|
||||
**Optional:**
|
||||
- Review title/headline
|
||||
- Upload images (2-5 max)
|
||||
- Would you recommend? (Yes/No)
|
||||
|
||||
**Form placement:**
|
||||
- "Write a Review" button opens modal or inline form
|
||||
- Position near rating summary
|
||||
|
||||
### Form Validation
|
||||
|
||||
**Requirements:**
|
||||
- Rating must be selected
|
||||
- Minimum review length (50 characters)
|
||||
- Show character counter: "50 / 500 characters"
|
||||
- Validate before submit
|
||||
|
||||
**Success:**
|
||||
- "Thank you for your review!"
|
||||
- "Your review is pending approval" (if moderation enabled)
|
||||
|
||||
## Trust Signals
|
||||
|
||||
### Verified Purchase Badge (CRITICAL)
|
||||
|
||||
**Display:**
|
||||
- Badge or checkmark: "✓ Verified Purchase"
|
||||
- Position near reviewer name
|
||||
- Green color or checkmark icon
|
||||
- Only for confirmed customers
|
||||
|
||||
**Why it matters:**
|
||||
- Builds trust (real customer, not fake)
|
||||
- Reduces suspicion of paid reviews
|
||||
- Higher credibility
|
||||
|
||||
### Helpful Votes
|
||||
|
||||
**Upvote/downvote system:**
|
||||
- "Was this review helpful?"
|
||||
- [👍 Yes (24)] [👎 No (2)]
|
||||
- Click to vote (one vote per user)
|
||||
- Powers "Most Helpful" sorting
|
||||
|
||||
**Benefits:**
|
||||
- Surfaces most useful reviews
|
||||
- Community validation
|
||||
- Reduces impact of unhelpful reviews
|
||||
|
||||
### Review Images (Optional)
|
||||
|
||||
Customer-uploaded photos (3-4 max per review, 60-80px thumbnails, click to enlarge). Visual proof increases trust and engagement.
|
||||
|
||||
### Store Responses (Recommended)
|
||||
|
||||
Seller replies below original review (indented, light gray background). Respond to negative reviews professionally - shows you care, addresses concerns without being defensive.
|
||||
|
||||
## SEO Integration
|
||||
|
||||
**AggregateRating Schema (CRITICAL):** Add structured data to show star ratings in search results. Include `ratingValue` (avg rating), `reviewCount`, `bestRating` (5), `worstRating` (1).
|
||||
|
||||
**SEO benefits:** Star ratings in search results, higher CTR, rich snippets. See seo.md for implementation details.
|
||||
|
||||
**Important:** Only include if reviews are real. Fake reviews violate Google guidelines.
|
||||
|
||||
## Display Patterns
|
||||
|
||||
**Individual review card:**
|
||||
Star rating (16-20px) + text + reviewer name (first name + initial) + date + verified badge + helpful votes. Truncate long reviews (200-300 chars) with "Read more".
|
||||
|
||||
**Mobile:**
|
||||
Single column, touch-friendly votes (44px), full-screen sort select, filter bottom sheet, "Load more" pagination.
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Star rating summary (average + count)
|
||||
- [ ] Rating distribution bar chart (5 to 1 stars)
|
||||
- [ ] Clickable bars to filter by rating
|
||||
- [ ] Sort dropdown (Most Recent, Most Helpful, Highest/Lowest)
|
||||
- [ ] Filter options (verified, with photos, by rating)
|
||||
- [ ] Individual reviews with: stars, text, name, date
|
||||
- [ ] Verified purchase badge
|
||||
- [ ] Helpful votes (upvote/downvote)
|
||||
- [ ] Review submission form (rating, text)
|
||||
- [ ] Form validation (minimum length, required rating)
|
||||
- [ ] "Read more" for long reviews
|
||||
- [ ] Store responses to reviews (recommended)
|
||||
- [ ] Review images (customer uploads, optional)
|
||||
- [ ] Mobile: Touch targets 44px minimum
|
||||
- [ ] Pagination or "Load more" button
|
||||
- [ ] No reviews state ("Be the first to review")
|
||||
- [ ] AggregateRating structured data (SEO)
|
||||
- [ ] ARIA labels for star ratings
|
||||
- [ ] Keyboard accessible (all interactions)
|
||||
@@ -0,0 +1,174 @@
|
||||
# Product Slider Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [When to Use Product Sliders](#when-to-use-product-sliders)
|
||||
- [Slider Patterns](#slider-patterns)
|
||||
- [Product Display](#product-display)
|
||||
- [Navigation Controls](#navigation-controls)
|
||||
- [Mobile Sliders](#mobile-sliders)
|
||||
- [Performance](#performance)
|
||||
- [Checklist](#checklist)
|
||||
|
||||
## Overview
|
||||
|
||||
Product slider (carousel) displays multiple products horizontally with navigation to scroll through them. Used for related products, recently viewed, bestsellers, and featured products.
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build carousels with navigation. This focuses on ecommerce product slider patterns.
|
||||
|
||||
**Key requirements:**
|
||||
- Horizontal scrolling of product cards
|
||||
- Arrow navigation (prev/next)
|
||||
- Optional dot indicators
|
||||
- Mobile: Swipe gesture support
|
||||
- Responsive product count (4-6 visible desktop, 2-3 mobile)
|
||||
- Lazy loading for off-screen products
|
||||
|
||||
## When to Use Product Sliders
|
||||
|
||||
**Use for:**
|
||||
- Related products (product page)
|
||||
- Recently viewed (product page, homepage)
|
||||
- "You May Also Like" (product page)
|
||||
- Bestsellers / Featured products (homepage)
|
||||
- "Frequently Bought Together" (product page)
|
||||
- New arrivals (homepage)
|
||||
- Category showcases (homepage)
|
||||
|
||||
**Don't use for:**
|
||||
- Main product images (use gallery instead)
|
||||
- Critical content (not all users scroll/swipe)
|
||||
- Checkout flow (keep linear)
|
||||
- Primary navigation (use grid for discoverability)
|
||||
|
||||
## Slider Patterns
|
||||
|
||||
**Continuous scroll:**
|
||||
- Shows 4-6 products at once (desktop)
|
||||
- Scroll left/right by 1-2 products at a time
|
||||
- Smooth animated transition (300-400ms)
|
||||
- Most common pattern
|
||||
|
||||
**Infinite loop (optional):**
|
||||
- Wraps to beginning after end
|
||||
- Good for small product sets (<10 items)
|
||||
- Creates continuous browsing feel
|
||||
- Not necessary for large sets
|
||||
|
||||
**Snap to alignment:**
|
||||
- Products snap to grid after scroll
|
||||
- Prevents partial product visibility
|
||||
- Better visual alignment
|
||||
- Improves browsing experience
|
||||
|
||||
**Auto-play (NOT recommended for products):**
|
||||
- Automatic scrolling without user action
|
||||
- Poor UX for product sliders (users lose control)
|
||||
- Only use for promotional banners/hero images
|
||||
- If using: Pause on hover, slow speed (5-7s)
|
||||
|
||||
## Product Display
|
||||
|
||||
**Product cards in sliders:**
|
||||
- Same cards as product grids (see product-card.md)
|
||||
- Simplified on mobile (less detail, smaller images)
|
||||
- Image, title, price minimum
|
||||
- Optional: Rating, "Add to Cart" (desktop only)
|
||||
- Adequate spacing between cards (16-24px)
|
||||
|
||||
**Responsive display:**
|
||||
- Large desktop (>1440px): 5-6 products visible
|
||||
- Desktop (1024-1440px): 4-5 products
|
||||
- Tablet (768-1024px): 3-4 products
|
||||
- Mobile (<768px): 2 products (sometimes 1.5 for scroll hint)
|
||||
|
||||
**Scroll hint on mobile:**
|
||||
- Show 1.5 products (partial visibility of next)
|
||||
- Indicates more content to swipe
|
||||
- Improves discoverability
|
||||
- Better than showing exact 2 products
|
||||
|
||||
## Navigation Controls
|
||||
|
||||
**Arrow buttons:**
|
||||
- Left/right arrows outside slider
|
||||
- Desktop: Always visible or show on hover
|
||||
- Mobile: Hidden (swipe gesture preferred)
|
||||
- Position: Vertically centered
|
||||
- Size: 40-48px touch targets
|
||||
- Disable left arrow at start, right arrow at end (no infinite loop)
|
||||
|
||||
**Dot indicators (optional):**
|
||||
- Show progress through slider
|
||||
- Each dot = one "page" of products
|
||||
- Position: Below slider, centered
|
||||
- Small (8-12px dots)
|
||||
- Only if many products (>12)
|
||||
- Less common for product sliders (more for hero carousels)
|
||||
|
||||
**Keyboard navigation:**
|
||||
- Tab through visible product cards
|
||||
- Arrow keys scroll slider (optional)
|
||||
- Focus management on scroll
|
||||
|
||||
## Mobile Sliders
|
||||
|
||||
**Touch gestures:**
|
||||
- Horizontal swipe to scroll
|
||||
- Native scroll momentum
|
||||
- Snap to product alignment
|
||||
- No arrow buttons (swipe is intuitive)
|
||||
|
||||
**Mobile-specific adjustments:**
|
||||
- 2 products visible (or 1.5 for hint)
|
||||
- Larger touch targets on products
|
||||
- Remove hover-only features (Quick View)
|
||||
- Faster scroll animations (200-300ms)
|
||||
|
||||
**Performance on mobile:**
|
||||
- Lazy load off-screen products
|
||||
- Smaller image sizes
|
||||
- Limit initial products loaded (8-10)
|
||||
- Load more on scroll
|
||||
|
||||
## Performance
|
||||
|
||||
**Lazy loading (critical):**
|
||||
- Only load visible products initially
|
||||
- Load adjacent products (left/right) on demand
|
||||
- Significantly improves page load time
|
||||
- Use Intersection Observer API
|
||||
|
||||
**Image optimization:**
|
||||
- Responsive images (smaller for mobile)
|
||||
- WebP format with fallback
|
||||
- Lazy load off-screen images
|
||||
- Optimized thumbnails (<300KB)
|
||||
|
||||
**Limit slider length:**
|
||||
- Max 20-30 products per slider
|
||||
- "View All" link to full category page
|
||||
- Improves performance
|
||||
- Prevents endless scrolling
|
||||
|
||||
## Checklist
|
||||
|
||||
**Essential features:**
|
||||
- [ ] 4-6 products visible (desktop), 2 (mobile)
|
||||
- [ ] Arrow navigation (desktop)
|
||||
- [ ] Swipe gesture (mobile)
|
||||
- [ ] Product cards with image, title, price
|
||||
- [ ] Responsive product count
|
||||
- [ ] Smooth scroll transitions (300-400ms)
|
||||
- [ ] Snap to product alignment
|
||||
- [ ] Lazy load off-screen products
|
||||
- [ ] "View All" link if many products (>20)
|
||||
- [ ] Disable arrows at start/end
|
||||
- [ ] Keyboard accessible (Tab through products)
|
||||
- [ ] Mobile: No arrows, swipe only
|
||||
- [ ] Optimized images (<300KB)
|
||||
- [ ] Spacing between products (16-24px)
|
||||
- [ ] ARIA labels on navigation (`aria-label="Previous products"`)
|
||||
- [ ] `role="region"` on slider container
|
||||
- [ ] NO auto-play for product sliders
|
||||
@@ -0,0 +1,101 @@
|
||||
# Search Component
|
||||
|
||||
## Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Search Placement](#search-placement)
|
||||
- [Autocomplete and Product Suggestions](#autocomplete-and-product-suggestions)
|
||||
- [Search Results Page](#search-results-page)
|
||||
- [Empty States](#empty-states)
|
||||
- [Recent and Popular Searches](#recent-and-popular-searches)
|
||||
- [Mobile Search](#mobile-search)
|
||||
|
||||
## Overview
|
||||
|
||||
Search is critical for ecommerce - users with search intent convert at higher rates. Provide fast, relevant product discovery with autocomplete.
|
||||
|
||||
**Assumed knowledge**: AI agents know how to build search inputs with icons and clear buttons. This guide focuses on ecommerce search patterns.
|
||||
|
||||
### Key Requirements
|
||||
|
||||
- Prominent search input (always accessible)
|
||||
- Instant autocomplete after 2-3 characters
|
||||
- Product suggestions with images
|
||||
- Fast, relevant search results
|
||||
- Filters to refine results
|
||||
- Empty state guidance
|
||||
- Mobile full-screen search modal
|
||||
|
||||
## Search Placement
|
||||
|
||||
**Desktop**: Navbar center (between logo and cart) or right side. Always visible, 300-500px width. Part of sticky navbar. Never hide in hamburger menu.
|
||||
|
||||
**Mobile**: Magnifying glass icon in top-right (44x44px minimum). Opens full-screen modal - eliminates distractions, maximizes suggestion space, better typing experience.
|
||||
|
||||
## Autocomplete and Product Suggestions
|
||||
|
||||
**Show suggestions** after 2-3 characters (not 1). Debounce 300ms to prevent excessive API calls.
|
||||
|
||||
**Display 5-10 product suggestions:**
|
||||
- Small image (40-60px), title, price
|
||||
- Clickable to product page
|
||||
- Optional: Category/brand suggestions, popular terms
|
||||
- Divide sections with headers
|
||||
- "View all results for [query]" footer link
|
||||
|
||||
**Backend integration**: Fetch from search API. Check with ecommerce platform's documentation for API reference.
|
||||
|
||||
## Search Results Page
|
||||
|
||||
**Header**: "Search Results for '[query]'" + result count ("24 products found"). Search bar visible and pre-filled for refining.
|
||||
|
||||
**Grid layout**: Same as product listings (see product-listing.md). 1-4 columns based on device.
|
||||
|
||||
**Sorting**: Relevance (default, unique to search), Price Low/High, Newest.
|
||||
|
||||
**Filters**: Sidebar (desktop) or drawer (mobile). Category, Price, Brand, Availability with result counts.
|
||||
|
||||
## Empty States
|
||||
|
||||
**No results**: "No results for '[query]'" with helpful suggestions (check spelling, try broader keywords, browse categories). "Browse All Products" button + links to popular categories.
|
||||
|
||||
**Loading state**: Product card skeletons (6-8 cards), minimum 300ms display to avoid flashing.
|
||||
|
||||
## Recent and Popular Searches
|
||||
|
||||
**Recent searches** (user-specific, localStorage): Show 3-5 recent searches when input focused (before typing). Helps re-search without retyping.
|
||||
|
||||
**Popular searches** (site-wide, from backend): Show 5-10 trending terms when focused. Pill/tag styling.
|
||||
|
||||
Display both on: Empty input focus (desktop dropdown), mobile modal open.
|
||||
|
||||
## Mobile Search
|
||||
|
||||
**Full-screen modal pattern:**
|
||||
- Header: Back button (44x44px) + search input (48px height, auto-focus, `type="search"`)
|
||||
- Content: Recent/popular searches (empty), autocomplete (typing), scrollable
|
||||
- Close: Back button, device back gesture, Escape key
|
||||
|
||||
## Ecommerce Search Checklist
|
||||
|
||||
**Essential features:**
|
||||
|
||||
- [ ] Prominent search input in navbar (desktop)
|
||||
- [ ] Search icon clearly visible (mobile)
|
||||
- [ ] Full-screen modal on mobile tap
|
||||
- [ ] Autocomplete after 2-3 characters
|
||||
- [ ] Debounced API calls (300ms)
|
||||
- [ ] Product suggestions with images, prices
|
||||
- [ ] "View all results" link in dropdown
|
||||
- [ ] Search results page shows query
|
||||
- [ ] Result count displayed
|
||||
- [ ] Sort by Relevance (default for search)
|
||||
- [ ] Filters for refining results (category, price, brand)
|
||||
- [ ] Empty state with helpful guidance
|
||||
- [ ] Loading state indicator (skeleton)
|
||||
- [ ] Recent searches (localStorage)
|
||||
- [ ] Popular searches (from backend)
|
||||
- [ ] Mobile: Auto-focus, large input (48px)
|
||||
- [ ] Keyboard navigation (arrow keys, Enter, Escape)
|
||||
- [ ] ARIA labels (`role="search"`, `aria-label`)
|
||||
- [ ] Accessible to screen readers
|
||||
Reference in New Issue
Block a user