Creating a Variant
This guide walks through adding a new product card variant as an example. The same pattern applies to any component slot.
Step 1: Create the Component
Create a new file in the slot directory:
src/templates/components/product-display/card/CardHighlight.tsxtsx
import type { Product } from '../../../../types';
interface Props {
product: Product;
}
export default function CardHighlight({ product }: Props) {
const discount = product.specialPrice
? Math.round((1 - product.specialPrice / product.price) * 100)
: 0;
return (
<div class="card bg-gradient-to-br from-base-100 to-base-200 shadow-lg hover:shadow-xl transition-shadow">
<figure class="relative">
<img
src={product.smallImageUrl}
alt={product.name}
class="w-full aspect-square object-contain"
loading="lazy"
/>
{discount > 0 && (
<span class="badge badge-error absolute top-2 right-2">
-{discount}%
</span>
)}
</figure>
<div class="card-body p-4">
<h3 class="card-title text-sm line-clamp-2">{product.name}</h3>
<div class="flex items-baseline gap-2">
{product.specialPrice ? (
<>
<span class="text-error font-bold">${product.specialPrice.toFixed(2)}</span>
<span class="text-text-muted line-through text-xs">${product.price.toFixed(2)}</span>
</>
) : (
<span class="font-bold">${product.price.toFixed(2)}</span>
)}
</div>
</div>
</div>
);
}Step 2: Register in Manifest
Add the variant to _manifest.json:
json
{
"slot": "card",
"domain": "product-display",
"description": "Product card shown in category grids and search results",
"variants": {
"standard": { "label": "Standard Card", "file": "CardStandard.tsx" },
"minimal": { "label": "Minimal Card", "file": "CardMinimal.tsx" },
"highlight": {
"label": "Highlight Card",
"description": "Gradient background card with prominent discount badge",
"file": "CardHighlight.tsx"
}
},
"default": "standard"
}Step 3: Add to Index
Update the slot's index.tsx to import and map the new variant:
tsx
import { getVariant } from '../../../page-config';
import CardStandard from './CardStandard';
import CardMinimal from './CardMinimal';
import CardHighlight from './CardHighlight';
const variants = {
standard: CardStandard,
minimal: CardMinimal,
highlight: CardHighlight,
};
export default function ProductCard(props) {
const variant = getVariant('product', 'card', 'standard');
const Component = variants[variant] || CardStandard;
return <Component {...props} />;
}Step 4: Use in Page Config
Enable the variant for a store by updating its page.json:
json
{
"pages": {
"product": {
"components": {
"card": "highlight"
}
},
"category": {
"components": {
"card": "highlight"
}
}
}
}Step 5: Regenerate Manifest
bash
bun run manifestStep 6: Build and Test
bash
bun run build
bun run devVariant Checklist
When creating a variant, ensure:
- [ ] Component accepts the same props as sibling variants
- [ ] Uses DaisyUI classes and UnoCSS utilities (not custom CSS where possible)
- [ ] Respects theme tokens (CSS custom properties, not hardcoded colors)
- [ ] Images use
loading="lazy"for off-screen content - [ ] Interactive elements have appropriate
data-controllerattributes if needed - [ ] Added to
_manifest.jsonwith label and description - [ ] Added to
index.tsxvariant map - [ ] Works at all breakpoints (mobile, tablet, desktop)
Source: src/templates/components/, scripts/generate-manifest.js