All projects
harmattan-cover

Harmattan Ghana

Harmattan Ghana

01

Overview

Project name

Harmattan Ghana

Harmattan Ghana

One-line description

A full-stack e-commerce platform and CMS-driven marketing site for a Ghana-based shea butter supply company.

My role

Full-Stack Developer, product architecture, frontend, backend API, database design, CMS setup, and deployment

Timeline

2025 to 2026

Category

E-commerce · Shea Butter

Platforms

Web · Vercel (SPA + Serverless API)

Tech stack

ReactViteTailwind CSSTanStack QueryExpressAuth.jsNeon PostgreSQLSanity CMSVercel

02

The Problem

Northern Ghana produces significant volumes of high-quality shea butter through women-led producer networks, but the trade chain around it is fragmented. Producers struggle to reach dependable buyers, logistics are poorly coordinated, pricing is unstable, and too much of the supply flow depends on informal intermediaries. Harmattan needed more than a brochure website. They needed a credible digital presence that could tell their story to investors and buyers, while also supporting real product discovery, ordering, and post-purchase tracking for customers across Ghana and international markets.

03

The Solution

I built a single platform that serves two purposes: a content-rich landing experience for brand storytelling, and a functional shop for browsing, purchasing, and tracking shea butter orders. Content editors manage the homepage, product catalogue, and shop settings through Sanity CMS, including an embedded Studio at /studio, without touching code. Customers can browse products with localised pricing, add items to a persistent cart, check out as authenticated users, and follow their order through a tracking timeline in their account dashboard. The result is a production-ready site that supports Harmattan's mission: connecting trusted Northern Ghana sourcing with scalable, reliable fulfilment for wholesale and retail buyers.

04

Key Features

  • CMS-driven landing page

    Hero carousel, about, problem statement, categories, offers, distribution model, testimonials, blog, and contact, all editable in Sanity with built-in fallbacks.

  • Product catalogue

    Category, price range, size, and status filters; sorting; product detail pages with size variants.

  • Geo-localised pricing

    Automatic currency detection and live exchange-rate conversion, with fallback rates when APIs are unavailable.

  • Shopping cart

    Drawer UI with localStorage persistence across sessions.

  • User accounts

    Email/password registration and optional Google sign-in via Auth.js.

  • Checkout & orders

    Authenticated checkout flow that creates orders with line items and shipping details.

  • Order tracking

    Per-order timeline (ordered → processing → shipped → delivered) in the customer account area.

  • Embedded content studio

    Sanity Studio built into the app and deployed alongside the storefront at /studio.

  • Responsive UI

    Mobile-first layout with light/dark theme support.

05

Technical Implementation

Architecture

React SPA talks to a serverless Express API on Vercel. Product and marketing content from Sanity CDN; transactional data (users, sessions, orders) in Neon PostgreSQL. React Context for cart, catalogue, and currency state; TanStack Query for server data caching. Browser → Sanity CDN (products, landing, images); /api/auth (Auth.js); /api/orders (Neon); /api/* (geo, exchange rates, Sanity proxy).

Backend

Express 5 API wrapped with serverless-http for Vercel. Routes cover user registration, Auth.js session handling, order CRUD, and proxies for geo-location, exchange rates, and Sanity CDN, each with fetch timeouts and cache headers suited to serverless.

Frontend

React 19 with Vite, React Router, and Tailwind CSS. Key pages: landing home, shop listing, product detail, checkout, login/register, and account area for order history and tracking.

Database

Neon PostgreSQL stores Auth.js tables (users, accounts, sessions), orders, order line items, and order tracking events. Order creation runs inside a database transaction so items and tracking milestones are written atomically.

APIs / Integrations

Sanity headless CMS for landing content, shop products, and settings. Auth.js JWT sessions with Neon adapter; credentials + optional Google OAuth. open.er-api.com for live USD exchange rates (proxied). geojs.io / ipwho.is for IP-based country detection.

Infrastructure

Deployed on Vercel with SPA rewrites, serverless API function (30s max duration), and build pipeline compiling embedded Sanity Studio into /public/studio. Environment variables for database, auth secrets, and Sanity across production and preview.

06

Challenges & Solutions

  • Serverless authentication

    Auth.js behind a Vite dev proxy required careful handling of changeOrigin and redirect URIs so OAuth callbacks worked locally and in production. JWT sessions for credentials provider while still using the Neon adapter for OAuth account linking.

  • Resilient multi-currency display

    Built a ViewerMoney context that chains geo-IP detection, live exchange rates, and a broad fallback rate table, ensuring prices always render even when upstream APIs fail.

  • CMS flexibility without breaking the site

    Landing and shop modules normalise CMS data and fall back to built-in defaults, so the storefront remains functional during setup or partial Sanity outages.

  • Transactional order integrity

    Wrapped order inserts (line items + pre-seeded tracking timeline) in a PostgreSQL transaction to prevent partial orders and give customers a consistent tracking experience from checkout.

07

Results

Shipped a live production platform at harmattanghana.com. Delivered a unified experience: brand storytelling, product discovery, checkout, and order tracking in one codebase. Enabled the Harmattan team to manage products and page content independently through Sanity Studio. Built for international buyers with automatic currency localisation across dozens of markets.

08

What I Learned

  1. 1.Headless CMS + fallbacks, pairing Sanity with built-in default content makes a CMS-powered site much safer to operate; editors get flexibility without risking a blank production page.
  2. 2.Serverless needs defensive I/O, timeouts, caching headers, and graceful degradation on third-party APIs (geo, rates) are essential when every API call runs inside a cold-starting function.
  3. 3.Separate content from transactions, keeping products in Sanity and orders in Postgres gives each system the right tool: fast, editable catalogue data vs. relational integrity for purchases.
  4. 4.Localised UX is a feature, not an afterthought, detecting country and formatting prices in the viewer's currency meaningfully improves trust for an export-oriented Ghanaian brand.

09

Links

LET'S WORKTOGETHER

I design and ship production-ready systems at the intersection of cloud infrastructure, full-stack engineering, and human-centred product thinking.

Send email · kuzagbechristopher@gmail.com