E-commerce for developers
The Next.js 14 and Shopify boilerplate that has everything you need to build and ship superior e-commerce in days, not months.
Crafted for reliability and high performance
Next.js 14
Shopify API
TailwindCSS
TypeScript
All you need for a fully equipped store
Customizable beautiful UI components built with shadcn/UI as well as pre-made landing, collection, product pages, and more.
Shopping Cart
Search Bar
Filters
Product Page
Wishlist
Product List
The best way to develop ecommerce with all the hard work done for you.
Best features for ambitious projects
Server Actions
Next.js App Router
RSC & Suspense
Shopify Webhooks
Google Analytics 4
Loading & Error Fallbacks
SEO Optimized
Light & Dark Mode
SSR Scroll Pagination
Save hours of repetitive boring code
Wishlist Button
Fetching Collections
@/components/wish-list/buttons
'use client'; import { useTransition } from 'react';import { useRouter } from 'next/navigation';import { Icons } from '@/components/icons';import { Button } from '@/components/ui/button';import { useToast } from '@/components/ui/use-toast';import { addToWishList, removeFromWishList } from '@/components/wish-list/actions';import { sendGAEvent } from '@/lib/google/send-ga-event';import type { Product } from '@/types/shopify'; interface WishListButtonProps { product: Product; isActive: boolean;} export const WishListButton = ({ product, isActive }: WishListButtonProps) => { const router = useRouter(); const { toast } = useToast(); const [isPending, startTransition] = useTransition(); const add = (): void => { startTransition(async () => { try { // Adding a product to wish list via Server Action await addToWishList(product.handle); // Sending event to Google Analytics // https://developers.google.com/analytics/devguides/collection/ga4/reference/events#add_to_wishlist sendGAEvent('add_to_wishlist', { currency: product.currencyCode, value: product.discount,isAvailable ? product.discount.price : product.price, items: [ { item_id: product.id, item_name: product.title, item_category: product.productType, price: product.discount.isAvailable ? product.discount.price : product.price, }, ], }); toast({ variant: 'success', title: `Added '${product.title}' to wish list`, }); // Refreshing page so that products would appear in wishlist router.refresh(); } catch { toast({ variant: 'destructive', title: 'Uh oh!', description: `Couldn't add '${product.title}' to wish list. Please try again.`, }); } }); }; const remove = (): void => { startTransition(async () => { try { await removeFromWishList(product.handle); toast({ variant: 'destructive', title: `Removed '${product.title}' from wish list`, }); router.refresh(); } catch { toast({ variant: 'destructive', title: 'Uh oh!', description: `Couldn't remove '${product.title}' from wish list. Please try again.`, }); } }); }; return ( <Button variant="outline" className="p-[13px] w-fit h-fit" title={!isActive ? `Add '${product.title}' to wish list` : `Remove '${product.title}' from wish list`} aria-label={!isActive ? 'Add to wish list button' : 'Remove from wish list button'} onClick={!isActive ? add : remove} > {isPending ? ( <Icons.loading size="20" className="animate-spin" /> ) : ( <Icons.wishList size="20" strokeWidth="2.25" fill={isActive ? 'black' : 'white'} /> )} </Button> );};
Any Questions?
Saved nerves. Quicker profit.
Pricing
Over 100 Copies Sold
Pay once. Build unlimited projects!
$149
Prebuilt beautiful UI components and pages
Commented code simple enough to understand (no, really)
Hundreds of hours of engineering pain avoided
Comprehensive features
Seamless scalability
Performance "she told you not to worry about"