Blocks
Pre-built page sections for common storefront layouts. These are larger compositions that combine multiple elements into complete sections.
Hero
Store hero section with logo, title, description, and stats.
// @validate
import { Hero } from '@shoppex/ui';
import type { Shop, Product } from '@shoppex/sdk';
const store = {
id: 'shop_123',
name: 'My Store',
slug: 'my-store',
currency: 'USD',
} satisfies Shop;
const products: Product[] = [];
export function Example() {
return <Hero store={store} products={products} />;
}
Props
Products array (used for stats)
Show “Visit Website” link if store has URL
Show star badge on logo if rated
Title Highlighting
Use curly braces in the store title to highlight text:
"Welcome to {Our Store}" → "Welcome to Our Store"
^^^^^^^^^ (muted color)
Custom Stats
// @validate
import { Hero } from '@shoppex/ui';
import type { Shop } from '@shoppex/sdk';
const store = {
id: 'shop_123',
name: 'My Store',
slug: 'my-store',
currency: 'USD',
} satisfies Shop;
<Hero
store={store}
stats={[
{ label: 'CUSTOMERS', value: '10k+' },
{ label: 'PRODUCTS', value: '500+' },
{ label: 'RATING', value: '4.9' },
]}
/>
Custom Logo
// @validate
import { Hero } from '@shoppex/ui';
import type { Shop } from '@shoppex/sdk';
const store = {
id: 'shop_123',
name: 'My Store',
slug: 'my-store',
currency: 'USD',
logo: 'https://cdn.example.com/logo.png',
} satisfies Shop;
<Hero
store={store}
renderLogo={(store) => (
<img
src={store.logo}
alt={store.name}
className="custom-logo-class"
/>
)}
/>
ProductGrid
Responsive product grid with optional filtering and sorting.
// @validate
import { ProductGrid } from '@shoppex/ui';
import type { Product } from '@shoppex/sdk';
const products: Product[] = [];
export function Example() {
return <ProductGrid products={products} />;
}
Props
columns
1 | 2 | 3 | 4 | 5 | 6
default:"4"
Number of grid columns
gap
'sm' | 'md' | 'lg'
default:"'md'"
Gap between cards
Show category filter buttons
Hide out of stock products
getProductHref
(product: Product) => string
Generate product link URL
With Filters and Sort
// @validate
import { ProductGrid } from '@shoppex/ui';
import type { Product } from '@shoppex/sdk';
const products: Product[] = [];
<ProductGrid
products={products}
showFilters
showSort
initialSort="newest"
hideOutOfStock
/>
Custom Rendering
// @validate
import { ProductGrid } from '@shoppex/ui';
import type { Product } from '@shoppex/sdk';
const products: Product[] = [];
function CustomProductCard({ product }: { product: Product; priority?: boolean }) {
return <div>{product.title}</div>;
}
<ProductGrid
products={products}
renderProduct={(product, index) => (
<CustomProductCard
key={product.uniqid}
product={product}
priority={index < 4}
/>
)}
/>
Loading State
// @validate
import { ProductGrid, ProductGridSkeleton } from '@shoppex/ui';
import type { Product } from '@shoppex/sdk';
const isLoading = false;
const products: Product[] = [];
export function Example() {
return isLoading ? (
<ProductGridSkeleton count={8} columns={4} />
) : (
<ProductGrid products={products} />
);
}
WhyChooseUs
Trust/features section with bento grid layout.
// @validate
import { WhyChooseUs } from '@shoppex/ui';
export function Example() {
return <WhyChooseUs />;
}
Props
title
string
default:"'Why Choose Us?'"
Section title
Large feature card on the left
Smaller feature cards on the right
layout
'bento' | 'grid' | 'list'
default:"'bento'"
Layout style
Custom Features
// @validate
import { WhyChooseUs } from '@shoppex/ui';
import { Shield, Zap, Star, Lock } from '@shoppex/ui/blocks';
export function Example() {
return (
<WhyChooseUs
title="Why Shop With Us?"
mainFeature={{
icon: Zap,
title: 'Lightning Fast',
description: 'Get your products instantly.',
stats: [
{ value: '50ms', label: 'Delivery' },
{ value: '100%', label: 'Uptime' },
],
backgroundText: '24',
}}
features={[
{
icon: Shield,
title: 'Secure',
description: 'Bank-level encryption.',
},
{
icon: Star,
title: 'Quality',
description: 'Premium products only.',
},
{
icon: Lock,
title: 'Private',
description: 'Your data stays yours.',
},
]}
/>
);
}
Layout Options
Bento (default)
Grid
List
Large card on left, 2x2 grid on right
Simple 4-column grid of equal cards
Vertical list layout
FAQ
Accordion FAQ section.
// @validate
import { FAQ } from '@shoppex/ui';
export function Example() {
return (
<FAQ
title="Frequently Asked Questions"
items={[
{
question: 'How do I receive my purchase?',
answer: 'After completing your purchase, you will receive an email...',
},
{
question: 'What payment methods do you accept?',
answer: 'We accept all major credit cards, PayPal, and crypto.',
},
]}
/>
);
}
Props
Allow multiple items open at once
Index of item to open by default
layout
'default' | 'cards' | 'minimal'
default:"'default'"
Visual style
Default FAQ Items
// @validate
import { FAQ, defaultFAQItems } from '@shoppex/ui';
export function Example() {
return (
<>
<FAQ items={defaultFAQItems} />
<FAQ items={[...defaultFAQItems, { question: 'Custom?', answer: 'Yes!' }]} />
</>
);
}
Store footer with links and social icons.
// @validate
import { Footer } from '@shoppex/ui';
import type { Shop } from '@shoppex/sdk';
const store = {
id: 'shop_123',
name: 'My Store',
slug: 'my-store',
currency: 'USD',
} satisfies Shop;
export function Example() {
return <Footer store={store} />;
}
Props
Store object (extracts name, logo, socials)
Show “Powered by Shoppex” link
With Link Sections
// @validate
import { Footer } from '@shoppex/ui';
import type { Shop } from '@shoppex/sdk';
const store = {
id: 'shop_123',
name: 'My Store',
slug: 'my-store',
currency: 'USD',
} satisfies Shop;
<Footer
store={store}
sections={[
{
title: 'Products',
links: [
{ label: 'All Products', href: '/' },
{ label: 'New Arrivals', href: '/new' },
{ label: 'Best Sellers', href: '/best' },
],
},
{
title: 'Support',
links: [
{ label: 'Contact Us', href: '/contact' },
{ label: 'FAQ', href: '/faq' },
{ label: 'Terms', href: '/terms', external: true },
],
},
]}
/>
Custom Copyright
// @validate
import { Footer } from '@shoppex/ui';
import type { Shop } from '@shoppex/sdk';
const store = {
id: 'shop_123',
name: 'My Store',
slug: 'my-store',
currency: 'USD',
} satisfies Shop;
<Footer
store={store}
copyright={
<>
© 2024 My Store. Built with{' '}
<a href="https://shoppex.io">Shoppex</a>
</>
}
/>