Skip to content
Software that ships
Headless WordPress · Astro 2026

dotdot.com — Web Platform Modernisation

Modernising a content-driven website with a headless WordPress and Astro architecture, improving technical SEO and performance foundations while integrating analytics and campaign tracking.

dotdot.com — Web Platform Modernisation project overview
Public homepage of www.dotdot.com (desktop), captured October 2026.

Overview

dotdot.com is a Hong Kong brand site that sells through campaigns, WhatsApp enquiries and payment links. The public site now runs as a static Astro build, while the marketing team keeps editing in WordPress at a separate admin domain. Publishing in WordPress triggers a rebuild, so the team keeps a familiar editor while visitors get fast, pre-rendered pages.

Development areas

  • ▹WordPress (admin domain) as the CMS; Astro static pages on the public domain
  • ▹Per-page Rank Math SEO fields rendered into the static HTML at build time
  • ▹Site-wide conversion event layer for WhatsApp, purchase, phone, booking and form actions
  • ▹Measured page-weight and LCP reductions after a performance pass

The challenge

Fast campaign pages without losing the editor

The brand runs on campaigns: product launches, promotions, events and articles, with enquiries arriving through WhatsApp and payment links. It needed a publishing workflow the marketing team already understood, fast public pages, search visibility, and reliable measurement of which campaigns turn into enquiries and purchases.

My role and responsibilities

From content model to deploy pipeline

I led the technical rebuild and worked through repeated review rounds with the client and their marketer.

  • Architecture: separated the WordPress editor from the public front end and designed how content flows between them
  • Front end: built the Astro pages, shared components and responsive layouts, porting the existing pages one by one
  • Content model: page-level custom post types and ACF fields so copy, prices and sections stay editable in WordPress
  • Delivery: build and deploy scripts with backups and a rollback path, kept strictly separate from the existing production WordPress
  • Measurement and performance: the conversion event layer, tag configurations and the performance pass described below

Architecture

WordPress → Astro

Content is fetched once per build, not per visit. Every field falls back to the copy the page was built with, so a blank or unreachable CMS still produces an identical page instead of a broken one.

  1. 01

    Edit

    Marketing team updates pages, prices and SEO fields in WordPress (separate admin domain)

  2. 02

    Publish

    Saving triggers an automatic rebuild — live in about 1–2 minutes

  3. 03

    Build

    Astro queries WPGraphQL at build time, with fallback copy for every field

  4. 04

    Serve

    Pre-rendered static pages and hashed assets served through Cloudflare

Kept in WordPress

Page copy (ACF)Products & pricesArticlesRank Math SEO fieldsImages

Technical SEO

SEO fields where the editors already work

Because the public site is static, plugin features only take effect if the build renders them. I wired the per-page SEO fields through and rebuilt the site-level pieces on the Astro side.

  • Per-page fields: Rank Math title, description, robots, canonical and social-sharing values rendered into each static page
  • Site level: sitemap index and robots served by the public site; the WordPress admin domain redirects to the dashboard and stays out of search
  • Faster discovery: IndexNow notifications fixed so search engines hear about changes sooner
  • Review workflow: AI-drafted SEO suggestions go into a queue that the marketer approves, edits or rejects before anything is applied

Performance optimisation

Measured before and after a performance pass

The pass re-encoded the 19 MB 4K hero video to a 2.1 MB 1080p version that starts after first render, kept the off-screen office video from loading until it nears the viewport, lazy-loaded below-the-fold product images, and gave hashed CSS/JS a one-year immutable cache through Cloudflare. HTML stays uncached so CMS edits appear immediately.

MetricBeforeAfterChange
Mobile · data transferred38.48 MB9.41 MB−75.5%
Mobile · Largest Contentful Paint1.255 s1.007 s−19.8%
Mobile · full load9.6 s7.1 s−26.0%
Desktop · data transferred31.39 MB9.07 MB−71.1%
Desktop · Largest Contentful Paint2.558 s1.221 s−52.3%
Desktop · Total Blocking Time868 ms746 ms−14.1%
Cumulative Layout Shift (both)00Unchanged

Method: synthetic Uptrends tests from Hong Kong (Chrome; iPhone 12 Pro on 4G, and 1600×900 desktop), run on the staging build before and after the 7 September 2026 deploy. These are single lab snapshots, not field Core Web Vitals, and no Lighthouse score is claimed. The largest remaining cost was about 8 MB of images — responsive image sizes and fewer font requests are the next step.

Measurement

Conversion events and campaign attribution

Most sales start with a click to WhatsApp, a phone call or a payment link, so pageviews alone said little. I added one site-wide event for every meaningful action and prepared the tag configuration that routes it to each platform.

  • Implemented on the site: a dd_conversion data-layer event for WhatsApp, purchase, phone, booking, form, quiz and coupon clicks, carrying conversion type, target, page and traffic source
  • Delivered for the client’s Google Tag Manager containers: GA4 events (including view_item and begin_checkout), Meta standard events and a Google Ads conversion tag that stays paused until its conversion label is supplied
  • Audit finding: Meta Pixel was counting every PageView twice; a fix was documented for the container
  • Checkout: purchases go through GoHighLevel payment links, with post-purchase redirects configured for tracking

Trade-offs and lessons

What the architecture costs

Static delivery made the site fast and resilient, but every site-wide plugin feature — sitemaps, redirects, schema — has to be rebuilt deliberately on the front end; the CMS can no longer do it implicitly.

The new site shared a server with the existing production WordPress, so every deploy backs up first, guards its target path and leaves the production webapp untouched. Builds run off-box because the original host could not run the build.

Project gallery

dotdot.com homepage on a phone

Need production software built, modernised or measured?

Get in touch