Case study
ORUVA — Jewelry E-Commerce
A live jewelry label for the Spanish and French market: a headless Shopify storefront built solo, from brand to deployment.
Design & development (solo) · 2026

Languages
Page routes
Unit-test files
Delivery markets
Overview
The problem & the approach
ORUVA started as a template storefront and became a real store: a warm, modern European jewelry label selling gold-toned and silver pieces meant to be worn every day, not saved for later. The storefront is built on Next.js 16 (App Router, Cache Components) and the Shopify Storefront API, with checkout handled by Shopify.
I owned it end to end: brand positioning, storefront design, the Shopify data model, the code, caching, deployment and monitoring. The store runs in English, Spanish and French, prices include VAT, and delivery is tracked to Spain and France.
The source code is private now that it is a commercial project, so this page walks through the decisions instead. I am happy to go through the code on a call.
What I owned
Defined the brand positioning and designed the storefront UI
Set up the App Router structure, caching and revalidation
Modelled the Shopify data contract (metaobjects, menus, policies) and built the tooling to seed and sync it
Integrated the Storefront, Admin and Customer Account APIs
Set up deployment on Vercel, environment validation, error monitoring and SEO plumbing
Product
What it does
Catalog & product pages
Collections with sorting, filters and pagination. Product pages with variant selection, an image gallery, VAT-inclusive pricing and live stock status.
Persistent cart & delivery estimate
A cart kept in sync with the Shopify cart across sessions, with a delivery estimator by country and a free-shipping threshold. Payment happens on Shopify checkout.
Predictive search
Instant suggestions from a dedicated API route that queries the Storefront API as the shopper types, announced to screen readers through a live region.
Customer accounts
Sign-in through the Shopify Customer Account API, with an account area for orders and saved addresses.
Wishlist
Saved products with optimistic add/remove, so the heart responds instantly and rolls back cleanly if the server disagrees.
Three languages
English, Spanish and French with locale-prefixed routes, translated interface text and translated Shopify content.
Newsletter & contact
A double opt-in newsletter and a contact form, both validated with Zod and rate limited.
Legal & consent
Cookie consent that gates analytics, plus privacy, terms, refund, shipping, legal-notice and cookie pages managed in Shopify.
Dark & light themes
A theme switch that follows the system preference and remembers the choice.
Screens
Product walkthrough



Engineering
How it is built
Content lives in Shopify, not in env vars
Hero, promo bar, FAQ, size chart, navigation and brand identity are Shopify metaobjects read through cached getters. Environment variables hold only secrets and deployment config, so a brand change never needs a rebuild. CLI scripts seed and sync that content.
Cache Components with webhook-driven purging
Pages are prerendered with `use cache` and tagged. Shopify webhooks, verified with an HMAC secret, invalidate exactly the tags that changed, so the catalog stays fresh without giving up static speed.
Failures are never cached
Cached getters throw instead of returning an empty fallback, so a short Shopify outage cannot poison the cache for hours. Fallbacks live in uncached wrappers, and the cart estimator sits in its own Suspense island.
Typed GraphQL end-to-end
GraphQL Code Generator turns the Storefront and Admin schemas into a typed SDK, and CI fails if the generated output drifts from the committed files.
OAuth done properly
Customer sign-in uses the authorization-code flow with PKCE (S256) and a state check. A proxy renews sessions and handles auth redirects.
Optimistic UI without stale rollbacks
Cheap toggles like the wishlist use `useOptimistic`. The cart uses request-id sequencing, so the latest server answer always wins over a slower earlier one.
Hardened delivery
Content-Security-Policy, HSTS and cross-origin headers, Zod-validated Server Actions, Upstash Redis rate limiting that holds across serverless instances, and store HTML sanitized before rendering.
Quality
Tested, typed and accessible
75 Vitest files covering server actions, services, auth, rate limiting, caching and Shopify helpers, with enforced coverage thresholds
Playwright suites: axe accessibility checks (WCAG 2.1 AA, light and dark) over the main routes, and an add-to-cart smoke test
Strict TypeScript with generated GraphQL types and no hand-written API shapes
ESLint, Stylelint and Prettier, plus a codegen drift check in CI
Sentry error reporting, with metadata, sitemap and robots rules generated for every language
Want to see it live?
The store is live: browse the catalog, switch language and add to cart. The source code is private, so I am happy to walk through it on a call.