Skip to content
All writing

· 3 min read

Next.js and headless WordPress, in 20 languages, alone

What I learned building DeeSpot solo: why headless WordPress was the right backend, how 5 custom REST endpoints carried the product, and what 20 locales really costs.

Next.jsWordPressi18n

DeeSpot is a Bangkok lifestyle directory I built end to end for a Singapore-headquartered client: 32 pages, 26 API routes, 20 languages, one engineer. The stack decision that made it possible as a solo build was the least fashionable one available: headless WordPress.

Pick the CMS your editors already know

The client's team lives in WordPress. I could have given them a modern headless CMS and a training problem, or WordPress and a working content pipeline on day one. The content team never had to learn anything, and I never had to answer CMS support tickets.

Headless keeps the trade honest: editors get the WordPress admin they know, users get a fast Next.js frontend that never touches PHP rendering.

Five endpoints carried the whole product

Stock WordPress REST routes get you posts and pages. A directory needs more: search that understands listings, autocomplete that responds while you type, and a way for editors to curate featured content.

That turned into five custom REST endpoints in a small plugin. Not fifty. Each one exists because a specific screen needed it, and each one returns exactly the shape that screen renders. When one engineer owns both sides of an API, you can afford to make the contract precise.

What 20 locales actually costs

Localizing into 20 languages sounds like a translation problem. It's mostly an architecture problem:

  • Every route exists 20 times, so URL structure has to be decided once, early, and never revisited. Slug-per-locale retrofits are misery.
  • Fallbacks are a product decision, not a technical one. When a Thai listing has no Japanese translation, someone has to decide what a Japanese user sees. Decide it before launch, not per bug report.
  • SEO multiplies with locales. hreflang tags, per-locale sitemaps and canonical URLs are not optional extras; they are why the locales exist at all.

Next.js made the mechanics manageable: locale-aware routing plus static generation means most pages are prebuilt HTML in every language, and the server does close to nothing per request.

Production is CloudFront doing the work

The site serves production traffic on AWS behind CloudFront and an ALB, with RDS Multi-AZ underneath. For a content-heavy directory, the honest observation is that the CDN does most of the serving. The origin's job is to be correct and boring; CloudFront's job is to be fast.

The solo-build lesson

Owning design to production alone forces one discipline: every component you add, you operate. That bias, fewer moving parts chosen for the team you actually have, is the most transferable thing I took from this build. It's also exactly the argument that made WordPress, of all things, the right answer.

Building something and want a hand? I take on freelance and contract work.

Start a project