Skip to main content
TekXpat

Transport · Blantyre

Harry Salamba Taxi

Harry Salamba drives his own taxi around Blantyre town and out to Chileka. There is no dispatcher and no office. A site for a business of one person has a single job: be found, be trusted, and put the phone number where a thumb already is.

Sector
Transport
Where
Blantyre, Malawi
Live at
harrysalamba.tekxpat.com

The brief

What they needed

  • Be found by someone searching for a taxi or an airport transfer in Blantyre.

  • Make calling or messaging Harry the easiest thing on every page.

  • Work on an old phone, on a weak connection, without asking anyone to fill in a form.

See it yourself

harrysalamba.tekxpat.com

The site is live. Open it, check it loads, search for the business. That is better evidence than a screenshot we control.

Visit the live site

What we built

The work

Four pages, no backend at all

No database, no forms and no API routes. The site is entirely static: there is nothing to breach, nothing to keep patched, and nothing that can be down while the pages still serve. For a business whose enquiry channel is a phone call, a contact form would have been a slower path to the same number.

Call and WhatsApp on every screen

A sticky bar on mobile keeps both actions within reach at all times, and the number is a real tel: link so a tap dials it.

Conversion tracking, not just visit counting

Taps on call, WhatsApp and email fire goal events, so the analytics can show which traffic actually produces enquiries rather than only how many people arrived.

Search presence for the searches that exist

TaxiService structured data, a separate airport transfers page, and the Blantyre neighbourhoods he covers named explicitly — because "taxi Blantyre" and "taxi to Chileka airport" are different searches by different people.

Built with

  • Next.js 15 (App Router)
  • TypeScript
  • Tailwind CSS
  • Fully static — no database, no API routes
  • Schema.org structured data (TaxiService)
  • Managed hosting on our own server

Decisions

Why it was built this way

The parts that took the longest and are hardest to see. These are the reasons this site exists to talk about, rather than a gallery of screenshots.

No fare appears anywhere on the site

Harry has not confirmed his fares, so the site publishes none. A price quoted online and a different one at the kerb loses that passenger permanently. Unconfirmed facts are held in a `tbc()` wrapper in the code and render as an honest gap that fills itself in the moment he confirms — they are never filled with a plausible guess.

The flyer says 24/7. The schema does not.

One driver with one car cannot literally answer at 03:00, and publishing round-the-clock opening hours that nobody picks up is a promise a passenger discovers at an airport at night. The copy says "call any time — day or night", which is true either way, and the structured data omits opening hours entirely until Harry confirms real ones.

The mobile menu is HTML, not JavaScript

It is a native <details> element rather than React state, so the header stays a Server Component and the menu opens with JavaScript disabled and before hydration finishes. On a mid-range Android over a slow connection, the gap before hydration is exactly when an impatient visitor taps the menu.

One phone number, four representations

The international +265 form is stored once and the displayed number, the tel: link and the wa.me link are all derived from it. A number can only ever be wrong in one place, and the site cannot show a local 0-prefixed form that a visitor roaming on a foreign network would be unable to dial.

See for yourself

harrysalamba.tekxpat.com is live right now

Open it on your phone. Time how long it takes to load. Search for the business on Google. Everything on this page is checkable, which is the only kind of claim worth making.

The other one

Phonex Taxi

Taxi and airport transfer service in Blantyre. A Next.js site with a booking system, set up to be found by people searching for a ride.

Read it →

Prefer to talk? WhatsApp us.