Problem
A food and grocery marketplace needed browse-to-checkout flows that held up under real catalog size, auth edge cases, and payment failures. Search traffic also needed product pages that actually rendered for crawlers.
Decisions
- Next.js with SSR for category and product discovery pages
- React storefront on the existing Laravel / Lumen APIs and MySQL
- Xendit for checkout, with honest UI for failed payments and gateway timeouts
- OAuth (email, Facebook, Google) plus account linking paths that survive partial failures
- Loyalty points and promotional surfaces on the homepage without burying the cart path
What I built
- Category browsing and product discovery with search, filter, and sort
- Account registration / login including OAuth providers
- Profile, loyalty points, and delivery address management
- Cart review, order summary, and checkout handoff
- SEO-conscious product rendering for organic discovery
Tech Stack
- Frontend: React, Next.js, SCSS
- Backend: Laravel / Lumen
- Data: MySQL
- Integrations: OAuth providers, Xendit payment gateway
Outcomes
- Live site: klikhoreca.com
- Catalog scale: 1,000+ products across 50+ categories
- Checkout wired through Xendit with loyalty points on the customer path
Context
Production commerce UI under real constraints: auth edge cases, payment error states, image weight, and SSR for search visibility.
Lessons Learned
- Clean information hierarchy beats decorative UI for grocery conversion.
- Image weight and bundle size show up immediately in bounce behavior.
- OAuth happy path is easy. Account linking and partial failures are the work.
- Payment providers need idempotent webhook handling and clear UI error states.
- SSR helps SEO only when product content and metadata stay consistent.
Screenshots





