Storefront Components
Storefront Components
The StorefrontRenderer supports 35+ components optimized for customer-facing pages. Components automatically adapt to the store's theme via CSS variables (--primary-color, --primary-rgb, --font-primary).
Layout Components
| Component | Props | Description |
|---|---|---|
Card | title, subtitle, footer, padding, style | Rounded card with optional header and footer |
BlockStack / Stack | gap, style | Vertical flex container |
InlineStack | gap, align (space-between, center, end), style | Horizontal flex container |
Grid | columns (number), gap, style | CSS grid |
Box | className, style | Generic container |
Divider / Separator | — | Horizontal rule |
Collapsible | title, defaultOpen | Expandable section with animated toggle |
Display Components
| Component | Props | Description |
|---|---|---|
Text | content, variant (see below), bold, color, as, style | Text with semantic variants |
Heading | content, level (1–4), style | Heading tag (h1–h4) |
Image | src, alt, width, height, rounded, border, shadow, fit, style | Lazy-loaded image |
Badge | content, tone (success, warning, critical, info, new), icon | Colored pill badge |
Icon | name (from allowlist), size, className, style | Lucide icon |
Banner | title, content, tone, action, actionLabel | Alert banner with optional action |
List | items (string[] or object[]), type (disc, number, none) | Ordered/unordered list |
Table | headers (string[]), rows (string[][]) | Responsive data table |
KeyValue | label, value | Label-value row |
Thumbnail | src, alt, title, subtitle | Image + text row |
Text Variants
| Variant | Style |
|---|---|
headingXl | 24px bold |
headingLg | 20px bold |
headingMd | 16px semibold |
headingSm | 14px semibold |
bodyLg | 16px regular |
bodyMd | 14px regular (default) |
bodySm | 13px gray-500 |
caption | 11px uppercase tracking |
Storefront-Specific Widgets
These components are unique to the storefront renderer — not available in the dashboard.
Rating / StarRating
Star rating display with half-star support.
{ "type": "Rating", "props": { "value": 4.5, "max": 5, "count": 128, "size": 16 } }Countdown
Live countdown timer with days/hours/minutes/seconds.
{ "type": "Countdown", "props": { "target": "2025-12-31T23:59:59Z", "label": "Sale ends in" } }TrustBadges
Row of trust/security icons. Uses defaults if no badges prop provided.
{
"type": "TrustBadges",
"props": {
"badges": [
{ "icon": "Shield", "label": "Secure Checkout" },
{ "icon": "Truck", "label": "Free Shipping" },
{ "icon": "RefreshCw", "label": "30-Day Returns" }
]
}
}ProductCard
Mini product card for upsells and cross-sells.
{
"type": "ProductCard",
"props": {
"image": "https://cdn.example.com/product.jpg",
"name": "Premium Widget",
"price": "৳999",
"comparePrice": "৳1,499",
"badge": "Sale",
"rating": 4.5,
"reviewCount": 42,
"action": { "type": "navigate", "to": "/products/premium-widget" }
}
}SocialProof
"X people bought this recently" urgency indicator.
{ "type": "SocialProof", "props": { "count": 24 } }StickyBar
Fixed top or bottom announcement bar.
{
"type": "StickyBar",
"props": {
"content": "Free shipping on orders over ৳2,000!",
"position": "top",
"actionLabel": "Shop Now",
"action": { "type": "navigate", "to": "/shop" }
}
}Newsletter
Email signup form with success state.
{
"type": "Newsletter",
"props": {
"title": "Stay Updated",
"description": "Get exclusive offers and new arrivals.",
"placeholder": "Enter your email",
"buttonLabel": "Subscribe",
"successMessage": "Thanks for subscribing!",
"action": { "type": "call_backend", "url": "https://myapp.com/api/subscribe" }
}
}Testimonial
Customer review card with avatar, stars, and verified badge.
{
"type": "Testimonial",
"props": {
"content": "Amazing quality! Will definitely order again.",
"author": "Sarah K.",
"role": "Verified Buyer",
"rating": 5,
"avatar": "https://cdn.example.com/avatar.jpg",
"verified": true
}
}VideoPlayer
Embedded video (YouTube or native).
{ "type": "VideoPlayer", "props": { "type": "youtube", "videoId": "dQw4w9WgXcQ", "title": "Product Demo" } }Carousel
Image/card slider with navigation dots.
{
"type": "Carousel",
"props": {
"items": [
"https://cdn.example.com/slide1.jpg",
"https://cdn.example.com/slide2.jpg"
]
}
}QuantitySelector
Stepper input with +/- buttons.
{ "type": "QuantitySelector", "props": { "bind": "quantity", "min": 1, "max": 10 } }Modal
Overlay modal with trigger text.
{
"type": "Modal",
"props": {
"trigger": "View Size Guide",
"title": "Size Guide",
"content": [
{ "type": "Table", "props": { "headers": ["Size", "Chest", "Waist"], "rows": [["S", "36", "30"], ["M", "38", "32"]] } }
]
}
}Input Components
| Component | Props | Description |
|---|---|---|
TextField | label, type, placeholder, helpText, error, bind | Text input with focus ring |
TextArea | label, placeholder, rows, bind | Multi-line text input |
Select | label, options (array of {value, label}), placeholder, bind | Dropdown select |
Checkbox | label, helpText, bind | Checkbox with label |
All input components support two-way data binding via the bind prop — the value is read from and written to state[bind].
Action Components
Button
{
"type": "Button",
"props": {
"label": "Add to Cart",
"variant": "primary",
"size": "md",
"icon": "ShoppingCart",
"iconRight": "ArrowRight",
"fullWidth": true,
"loading": "{{state.submitting}}",
"action": { "type": "add_to_cart", "sku_id": "{{context.product_id}}" }
}
}Variants: primary (theme color), secondary (white border), outline (border only), plain (text link), critical (red)
Sizes: sm, md (default), lg
Link
{ "type": "Link", "props": { "label": "Learn more", "url": "https://example.com", "external": true } }Feedback Components
| Component | Props | Description |
|---|---|---|
Alert | content, tone | Colored alert box |
Spinner | size | Loading spinner in theme color |
Progress | value (0–100), label, showValue, color | Progress bar |
Compound Components
| Component | Props | Description |
|---|---|---|
Tabs | tabs (array of {label, content}), defaultTab | Tabbed content |
Accordion | items (array of {label, content}) | Expandable FAQ-style sections |
Available Icons
40 icons from Lucide: ShoppingCart, Star, Truck, Shield, Gift, Heart, Tag, Check, X, AlertCircle, Info, ChevronDown, ChevronRight, ChevronLeft, ExternalLink, Loader2, Package, Clock, Zap, Mail, Phone, MapPin, CreditCard, RefreshCw, ThumbsUp, MessageCircle, Play, Eye, Award, Percent, Bell, ArrowRight, Lock, BadgeCheck, Flame, Users, TrendingUp, Timer, Copy, Share2.
Template Expressions
All props support {{context.x}} and {{state.x}} template expressions:
{ "type": "Text", "props": { "content": "Hello {{context.customer_name}}, you have {{context.cart_item_count}} items" } }Supported expressions:
{{context.field}}— page context (product_id, store_id, etc.){{state.field}}— extension local state{{!context.field}}— negation{{context.field === 'value'}}— equality check{{context.field !== 'value'}}— inequality check
Conditional Rendering
Any component can be conditionally hidden:
{ "type": "Banner", "props": { "when": "{{context.is_logged_in}}", "content": "Welcome back!" } }
{ "type": "Button", "props": { "visible": "{{!state.submitted}}", "label": "Submit" } }