Storefront Page React template for Tailwind CSS v4
v1.0.0Added in 1.14.0
A React ecommerce store template: free shipping bar, hero, collections, a filterable product grid with quick add, a cart drawer and reviews.
A small brand's store home page. The strip on top states the free shipping threshold and can be closed. Shop the collection glides down to the grid; a collection tile filters the grid to that collection. In the grid, the collection chips (a swipeable row on phones) filter live and the count is announced; from 1024px On sale, In stock, a price select and a sort select sit beside them, below 1024px Filters opens a sheet (a bottom sheet on phones) with sort, price and availability chips and Show products. Products are two per row on phones. Every card is one link that lifts on hover; its swatches (arrow keys inside the group) recolor the drawn photo, the heart saves it, and Add to cart puts that color in the cart and opens the cart drawer, a side panel on desktop and a bottom drawer on phones, with quantity steppers, swipe or undo to remove, a free shipping progress bar and checkout. The featured product band has a gallery (thumbnails, swipe, a full-screen viewer), color swatches that redraw the photos, a size select, a quantity stepper and Add to cart; on phones a bar with Add to cart slides up from the bottom while that button is off screen. Reviews filter by star and sort; the newsletter form validates the email and confirms.
Storefront Page is a Pro React template in the React website templates category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add storefront-page, together with Marketing Section, Marketing Header, Marketing Footer, Newsletter Section, Banner and 15 more and the npm packages lucide-react and motion.
Built with
The sections this page is made of. In the full-screen preview, hold Alt to outline each one on the page.
Add to a project
Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup
npx wingo-ui@latest add storefront-pageStorefront Page is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans
Usage
Import StorefrontPage from @/components/templates/storefront-page.
// app/page.tsx
"use client"
import Link from "next/link"
import { StorefrontPage, type StorefrontAddToCart } from "@/components/templates/storefront-page"
import type { CartItem } from "@/components/ui/cart-drawer"
async function addToCart(item: StorefrontAddToCart) {
await fetch("/api/cart", { method: "POST", body: JSON.stringify({ line: item.lineId, quantity: item.quantity }) })
}
async function checkout(items: CartItem[]) {
const response = await fetch("/api/checkout", { method: "POST", body: JSON.stringify(items) })
const { url } = await response.json()
window.location.assign(url)
}
export default function HomeRoute() {
return <StorefrontPage linkComponent={Link} freeShippingThreshold={50} onAddToCart={addToCart} onCheckout={checkout} />
}Props
productsdefault"STOREFRONT_PRODUCTS"StorefrontProduct[]{ id, title, collection, price, compareAtPrice?, colors: { name, value }[], kind, images?, sizes?, rating?, reviewCount?, badge?, addedAt?, rank?, description?, maxQuantity?, soldOut?, href?, favorite? }. kind picks the drawn photo (notebook, pocket, planner, pen, mug, pouch) in the chosen color; images (one per color) replace it. Quick add uses the first size.
collectionsdefault"STOREFRONT_COLLECTIONS"StorefrontCollection[]{ id, title, description?, kind, color, image?, href? } tiles and grid chips; a product joins one by its collection id. An empty array hides the tiles.
featureddefault"STOREFRONT_FEATURED"StorefrontFeatured | nullA product (the StorefrontProduct shape) plus eyebrow and highlights, shown in the band with the gallery, swatches, size select and Add to cart. null hides it.
perksdefault"STOREFRONT_PERKS"StorefrontPerk[]{ icon?, title, description } tiles: shipping, returns, guarantee. An empty array hides them.
reviewsdefault"STOREFRONT_REVIEWS"ReviewData[]The reviews of the featured product, in the Reviews shape. An empty array hides the section.
reviewsSummarydefault"STOREFRONT_REVIEWS_SUMMARY"ReviewsSummaryData{ average, count, distribution, aspects? } when reviews is one page of many.
priceRangesdefault"STOREFRONT_PRICE_RANGES"StorefrontPriceRange[]The price filter choices as [min, max) pairs in major units; null is an open end. Any price is always first.
labelsPartial<StorefrontPageLabels>Every string on the page: brand, announcement, hero, section headings, filters, card and cart copy, newsletter, footer. Some are functions (announcement, productCount, quickAddLabel, featuredNote, photo).
currencydefault"USD"stringISO currency of every price, the threshold and the cart.
localedefault""stringIntl locale for prices and counts; empty uses the UIProvider's, else en-US.
freeShippingThresholddefault50numberThe order total for free shipping: the announcement strip, the note under Add to cart and the cart's progress bar. 0 hides all three.
shippingdefault6number | nullThe flat delivery price under the threshold, in the note under Add to cart and the cart summary; null prints Calculated at checkout.
defaultCollectiondefault""stringThe collection id the grid starts on; empty is All.
defaultSortdefault"featured""featured" | "newest" | "price-asc" | "price-desc" | "rating"The grid's starting order. featured follows rank with sold out items last.
cartItemsCartItem[]The cart, controlled. Quick add and Add to cart append or bump a line (id product:color:size).
defaultCartItemsCartItem[]The starting cart when it is not controlled; empty by default.
onCartItemsChange(items: CartItem[]) => voidEvery cart change: adds, quantity steps and removals.
cartOpenbooleanThe cart drawer, controlled.
defaultCartOpendefaultfalsebooleanStarts with the cart drawer open.
onCartOpenChange(open: boolean) => voidThe drawer opened or closed.
onAddToCart(item: StorefrontAddToCart) => void | Promise<unknown>{ product, color?, size?, quantity, lineId }. A returned promise keeps the button loading; a rejection adds nothing and announces labels.addFailed.
onCheckout(items: CartItem[]) => void | Promise<unknown>The cart's checkout button; a promise keeps it loading. Without it the button links to cartProps.checkoutHref (default /checkout).
onFavoriteChange(product: StorefrontProduct, favorite: boolean) => void | Promise<unknown>A heart was toggled; a rejection rolls it back.
onSubscribe(email: string) => void | Promise<unknown>The newsletter form; without it a 900 ms pretend, then the success line.
columnsdefault43 | 4Products per row from 1024px; three from 768px, two on phones.
tonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"Accents: the rating stars, the review bars and filters.
ctaTonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"Shop the collection, Add to cart, the sticky bar, checkout and the newsletter button.
favoriteTonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"The heart on a saved product; neutral is white on the photo.
saleTonedefault"danger""neutral" | "brand" | "success" | "warning" | "danger" | "info"Sale prices, the discount chip and the Sale tag on the photo (a markdown is a status).
radiusdefault"lg""none" | "sm" | "md" | "lg"Corners of the product, collection, buy box and perk cards: 0 / 12 / 16 / 24px; photos inside follow.
backgrounddefault"soft""plain" | "soft" | "glow" | "aurora" | "grid" | "dots"The main background: plain is the bare page color; the others tint the page and add a wash, a glow, an aurora, a grid or dots over the first screen.
backgroundColordefault"oklch(0.72 0.07 70)"stringThe tint of the main background, a warm sand by default.
bandBackgrounddefault"muted""muted" | "tinted" | "gradient" | "dots"The secondary background of every second section (collections, the featured product, perks). Cards inside are lifted above it.
bandColordefault"oklch(0.72 0.07 70)"stringThe tint of tinted and gradient bands; left equal to backgroundColor it follows it.
showAnnouncementdefaulttruebooleanThe free shipping strip above the header (needs freeShippingThreshold above 0).
showCollectionsdefaulttruebooleanThe collection tiles.
showFeatureddefaulttruebooleanThe featured product band.
showReviewsdefaulttruebooleanThe reviews with the rating summary.
showPerksdefaulttruebooleanThe shipping, returns and guarantee tiles.
showNewsletterdefaulttruebooleanThe newsletter signup.
stickyAddToCartdefaulttruebooleanBelow 768px, a bar with Add to cart slides up while the featured product is on screen and its own button is not.
headerdefaulttruebooleanThe sticky header with the brand, section links, account and the cart button. Off, the cart button moves to the grid's toolbar.
footerdefaulttruebooleanThe footer with Shop, Help and Company links.
headerPropsPartial<MarketingHeaderProps>Anything for MarketingHeader (layout, variant, items...); wins over the page's own values.
footerPropsPartial<MarketingFooterProps>Anything for MarketingFooter (variant, columns, socials, newsletter...).
bannerPropsPartial<BannerProps>Anything for the announcement Banner (tone, variant, persistKey, action...).
galleryPropsPartial<ProductGalleryProps>Anything for the featured ProductGallery (thumbnails, zoom, aspect...).
reviewsPropsPartial<ReviewsProps>Anything for Reviews (layout, onWriteReview, hasMore, onLoadMore...).
newsletterPropsPartial<NewsletterSectionProps>Anything for the NewsletterSection (layout, bullets, subscribers...).
cartPropsPartial<CartDrawerProps>Anything for the CartDrawer (showCoupon, couponProps, taxRate, note, size, checkoutHref...); items and open stay with the page, and onCheckout wins over checkoutHref.
animateIndefaulttruebooleanThe hero rises in once when the page mounts on the client; never during hydration, under reduced motion or in thumbnails.
linkComponent(props: LinkComponentProps) => ReactNodeThe router link for the product, header and footer links (next/link in an app).
classNamestringClasses for the root.
classNamesPartial<Record<StorefrontPageSlot, string>>Classes for announcement, header, hero, collections, collection, shop, toolbar, filters, grid, product, photo, featured, gallery, buyBox, stickyBar, reviews, perks, newsletter, cart and footer.
Parts
STOREFRONT_PAGE_SAMPLE
constantAll the sample content in one object: products, collections, featured, perks, reviews and the summary.
STOREFRONT_PRODUCTS
constantEight Fieldnote products: notebooks, a pocket set, a planner, pens, a mug and a pouch, two on sale and one sold out.
STOREFRONT_COLLECTIONS
constantNotebooks, Planners, Writing and Desk goods.
STOREFRONT_FEATURED
constantThe Field Notebook with three sizes, four colors and three highlights.
STOREFRONT_PERKS
constantFree shipping, 60-day returns, a binding guarantee and plastic-free packaging.
STOREFRONT_REVIEWS
constantSix Field Notebook reviews, one with a reply from the shop.
STOREFRONT_REVIEWS_SUMMARY
constant4.8 from 1,284 reviews with the star counts and three topics.
STOREFRONT_PRICE_RANGES
constantUnder $20, $20 to $40 and $40 and up.
DEFAULT_STOREFRONT_PAGE_LABELS
constantThe English strings.
drawStorefrontProduct
function(kind, color, view?) returns an svg data url of a drawn product shot (views front, open, angle, detail), for an img, a gallery or a cart line image.
StorefrontPageProps
typeProps of StorefrontPage, including the attributes of the root element.
StorefrontPageLabels
typeEvery string of the page.
StorefrontPageSlot
typeThe keys of classNames.
StorefrontPageRadius
type"none" | "sm" | "md" | "lg".
StorefrontPageSort
type"featured" | "newest" | "price-asc" | "price-desc" | "rating".
StorefrontPageColumns
type3 | 4.
StorefrontPriceRange
type[min, max) in major units; null is an open end.
StorefrontArtView
type"front" | "open" | "angle" | "detail".
StorefrontAddToCart
typeWhat onAddToCart receives: { product, color?, size?, quantity, lineId }.
StorefrontProduct
typeOne product of the grid.
StorefrontProductKind
type"notebook" | "pocket" | "planner" | "pen" | "mug" | "pouch": the drawn shots.
StorefrontColor
type{ name, value }: a swatch and the color of the drawn shot.
StorefrontSize
type{ value, label, description?, price? }: a size option, its own price if it differs.
StorefrontCollection
typeOne collection tile.
StorefrontFeatured
typeA StorefrontProduct plus eyebrow and highlights.
StorefrontPerk
type{ icon?, title, description }.
Examples
Brand accents
ctaTone and favoriteTone on an aurora page with tinted bands: orange Add to cart, checkout and newsletter buttons, red hearts.
A returning shopper
defaultCartItems with two lines and the drawer open: the free shipping bar, steppers and the summary.
A lean catalog
Three columns, square-ish cards, starting on Notebooks sorted by price, without collections, reviews or perks.
When the cart fails
onAddToCart rejects: the button spins, nothing lands in the cart and the failure is announced.
Inside a site layout
No header, footer or announcement, on a plain page with dotted bands: the cart button moves to the grid's toolbar.
Dependencies
Files
- components/templates/storefront-page.tsx
- components/templates/storefront-page-data.ts
FAQ
Is the React Storefront Page template free?
The preview, props and docs are free; copying the source needs a Pro plan. See plans.
How do I install Storefront Page?
Run npx wingo-ui@latest add storefront-page. It also adds the Wingo UI items it builds on (Marketing Section, Marketing Header, Marketing Footer, Newsletter Section, Banner and 15 more) and the npm packages lucide-react and motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/storefront-page.
How does Storefront Page behave on phones?
In the grid, the collection chips (a swipeable row on phones) filter live and the count is announced; from 1024px On sale, In stock, a price select and a sort select sit beside them, below 1024px Filters opens a sheet (a bottom sheet on phones) with sort, price and availability chips and Show products.
See also
Related guides
- Nextjs Restaurant Template: Open Now, Menu, Book a Table
Build it: screens and apps10 min read