Heaven KL Local Spa

Heaven KL Local Spa is a 72-page spa website covering eight service areas across Kuala Lumpur, Selangor, and Johor. Built with Next.js and TypeScript, it separates 21 service pages from 8 location pages and adds therapist profiles, a pricing page, an FAQ, and a dedicated booking page — so that a search for a treatment and a search for a treatment near a place land on different, appropriate pages.

Role
Full stack development, local SEO
Year
2025
Stack
Next.js, TypeScript, React, Tailwind CSS
Heaven KL Local Spa homepage

The structural problem

A spa operating in eight areas faces a choice that decides the whole project. Put everything on one page and the business competes in one city while being invisible in the other seven. Generate one page per area with only the place name swapped and the site looks like a doorway network, which search engines filter out rather than reward.

The requirement was genuine coverage for Sungai Besi, Seri Kembangan, Setapak, Desa Sri Hartamas, Kuala Lumpur, Johor Bahru, Permas Jaya, and Gelang Patah — without the thin, templated pages that get local sites demoted.

Two layers, not one

Service pages and location pages were built as separate layers with separate jobs. A service page explains one treatment in full — what it is, who it suits, what it involves. There are 21 of them, covering everything from deep tissue and Thai to hot stone, couples, and four-hand massage.

A location page does a different job: it explains availability, access, and booking for one area, and links to the services offered there. It does not restate the treatment content, because restating it is exactly what produces duplicate pages.

That separation means the two search behaviours — researching a treatment, and looking for somewhere nearby — are served by pages built for each, rather than by one page trying to do both badly.

The pages that close the booking

Local service searches convert on specifics, and the specifics people want are usually withheld. Sites that hide prices behind an enquiry form lose the comparison before it starts.

So the build treats the closing information as pages in their own right: a pricing and packages page, an FAQ, and a dedicated booking page reachable from anywhere on the site. Seven therapist profile pages add the detail that generic spa sites cannot offer — who the customer will actually see.

Twenty-one editorial articles sit above all of this, targeting the research-stage questions that come before someone knows which treatment they want, and linking down into the service and location pages.

Technical approach

Next.js static generation delivers every one of the 72 URLs as complete HTML, so no page depends on JavaScript execution to be crawled or read. All 72 are declared in a sitemap at the site root.

Tailwind CSS keeps the shipped CSS small across a site built largely from repeated templates, and TypeScript models the service, location, and pricing content so that a page cannot ship with a field missing. Supporting pages — privacy policy, booking terms — are part of the same system rather than afterthoughts, because a local business site is judged on completeness as much as on content.