Malaika AfridiWorkAboutAvailable for work
← All work

Web app · 2025

Banjulo

The Gambia's marketplace — rescued from a client-only prototype and rebuilt on Next.js. Same interface, same Supabase backend, a different foundation underneath: pages that render on the server, describe themselves to search engines, and load on a mobile network.

Banjulo marketplace landing page
The marketplace as buyers see it — unchanged by the migration, which was the point.

Overview

Banjulo connects Gambian sellers with buyers at home and across the diaspora. It was built quickly in Vite through Lovable: a client-only single-page app that rendered nothing until its JavaScript arrived. For a marketplace whose customers find it through search and reach it over mobile networks, that is not a detail — it is a ceiling on how many people ever see it.

Rescue rather than rebuild. The interface and the Supabase backend stayed exactly as they were; only the rendering foundation was replaced. The result is invisible to anyone using the site and total underneath it.

Role

Full-stack — migration & rebuild

Timeline

2025 · shipped

Stack

Next.js 15 · App RouterReact 18Tailwind CSS · shadcn/uiSupabase — auth & PostgresTanStack Query
1The marketplace

Local sellers, diaspora buyers

Three audiences on one platform: Gambians buying at home, sellers reaching further than a market stall allows, and a diaspora shopping back into the country. That mix is the reason the rendering problem mattered — the people furthest away are the ones most likely to arrive through a search result or a shared link. The landing page above is what they see, and it is unchanged: the interface was never the problem.

2The migration

Vite and Lovable to Next.js

The whole project in one picture. Before: a client-rendered SPA with blank HTML first, weak SEO, no asset optimisation, and a slow first paint on mobile. After: server-rendered pages, per-route metadata and Open Graph, next/image and code-splitting — and the same interface, with Supabase intact. Nothing was redesigned; the layer beneath it was replaced.

Before and after: client-rendered SPA against Next.js App Router with SSR
Rescued the existing app, rebuilt the rendering layer — no redesign.
3The flow

What the product actually does

Listing, discovery and purchase, explained on the page rather than assumed. These are the routes that most need to exist as real HTML: a buyer searching for a Gambian craft should land on a page a search engine could read in the first place.

How Banjulo works — listing, discovery and purchase
The routes with the most to gain from being indexable.
4The story

Why the platform exists

A marketplace with a reason behind it — Gambian artisans and sellers reaching buyers they could not otherwise meet. Worth saying plainly on the site, and worth rendering on the server so it can be found by someone who has never heard of it.

About Banjulo — the platform's purpose
The page a first-time visitor arrives on from a shared link.

The challenge

What made it hard

A client-rendered app serves an empty shell first. Crawlers receive no content to index, and a buyer on a slow connection watches a blank screen while the bundle downloads — the two things a marketplace can least afford.

Nothing described a page to anything outside the browser. With no per-route metadata and no Open Graph tags, every link shared into WhatsApp or Facebook looked identical and said nothing about what sat behind it.

The obvious fix — start again — would have thrown away a working interface and a working Supabase backend in order to solve what was only a rendering problem.

Approach

How it was built

Migrated to Next.js 15 on the App Router so pages render on the server and arrive as real HTML on the first byte, rather than as an empty div waiting for a bundle.

Per-route metadata and Open Graph, so each page describes itself to a search engine and to every app a link gets pasted into.

The framework's own optimisations came with the move — next/image, font optimisation and code-splitting — which matter most on exactly the mobile networks this audience is on.

Claude Code carried the mechanical half: converting routing, moving components to the server, wiring metadata. The judgement calls stayed deliberate — what genuinely needed server rendering, keeping the Lovable interface verbatim rather than quietly improving it mid-migration, and where performance actually mattered.

Outcome

What shipped

Client-only SPA to server-rendered pages, with real HTML on the first byte.

No SEO to per-route metadata and Open Graph across every route.

Unoptimised assets to next/image, font optimisation and code-splitting.

Zero redesign and zero backend rewrite — Supabase auth and data untouched.

Next project

HUUMO

→

Want something like this?

Tell me what you're building and I'll tell you honestly how I'd approach it. Replies within hours.

Prefer email? Write to me directly at — it reaches the same inbox.

© 2026 Malaika AfridiXGitHubLinkedInUpworkEmail