
Problem
I wanted a storefront that felt real without faking production status. The challenge was combining editable content, believable product flow, and a clear demo boundary.
Context / users
Soap Stache is the storefront side of a small-brand commerce build. It handles catalog browsing, merchandising, cart behavior, policy pages, and checkout handoff. The Sanity studio lives in a separate repo.
My role
I owned the storefront architecture, route structure, component composition, cart state, Sanity integration, Stripe demo wiring, metadata setup, and frontend implementation.
Solution
I built it in Next.js 15 with the App Router, GROQ-fed Sanity content, React Context cart state, and localStorage persistence. The checkout flow posts cart data to an internal API route and redirects through Stripe in demo mode.
- App Router storefront with marketing pages, policy pages, product routes, and checkout success flow
- Sanity-backed catalog content and media integration
- Persistent shopping cart with quantity management and derived totals
- Stripe checkout handoff configured for demo/test use
- Structured metadata, canonical configuration, robots rules, and JSON-LD scaffolding
- Responsive merchandising sections for featured products, reviews, and brand storytelling
Architecture
The codebase is split cleanly: `app/` for routes and layout, `components/` for reusable UI, `contexts/` for cart state, and `lib/` for Sanity and Stripe helpers. The homepage is assembled from smaller sections instead of one oversized page component. Some catalog data is still fetched client-side with `useEffect`, which keeps the build simpler but is weaker for SEO than server-rendered or statically generated catalog pages.
Engineering Details
- • React Context manages cart state across the app, with localStorage used to restore cart contents between sessions
- • Cart items use a composite identifier strategy so product variants/types can be tracked independently
- • Product images are resized and quality-tuned through Sanity URL builders instead of shipping original assets directly
- • The app injects structured data and preconnect hints for external services such as Stripe and Google Fonts
- • ProductGrid includes explicit loading, error, retry, and empty states instead of assuming content always exists
- • Demo mode is enforced in both the UI and the README so the project does not imply live order processing
Outcome
- Produced a believable storefront demo that feels closer to a real product build than a static mockup
- Created a reusable reference pattern for CMS-backed catalog sites with a safe checkout demonstration layer
- Demonstrated frontend architecture choices that balance polish, maintainability, and realistic commerce behavior
- Gave the portfolio a stronger example of product thinking than a brochure-style site alone
Tradeoffs / Limits
- • This repo does not present a full production commerce stack: there is no visible auth layer, order persistence, inventory enforcement, or automated test suite
- • Some catalog data is fetched client-side, which is simpler to build but weaker for SEO than server-rendered or statically regenerated catalog pages
- • The companion Sanity Studio repo is referenced in the README but not bundled with this codebase, so schema-level claims should stay modest unless both repos are reviewed together
- • A few implementation details still need cleanup, including mismatched SEO/domain configuration and asset references in layout metadata
Why It Matters
It shows storefront architecture, reusable stateful UI, and a clear line between demo behavior and production commerce.
Like what you see?
Feel free to reach out if you have questions about this project or want to chat about working together.