Overview
A launch website for a residential development sold off-plan, run from your own WordPress and WooCommerce.
The visitor scrolls the construction calendar. The building is drawn from your project's own numbers and rises floor by floor while the payment plan fills beside it, so wherever they stop they see what will stand by then and what they would have paid. Every lit window is a home still for sale; stop on a floor and its homes unfold into cards.
What you get
- A Next.js website (the part visitors see) that reads everything from your WordPress: the development, every home and its price, stock, reservations, menus, posts, logo and SEO. Your sales team edits in wp-admin; the site updates within seconds.
- Four ready-made looks, each designed for its market — not a recolour:
| Look | Demo development | Market details |
|---|---|---|
| Creek (Gulf) | Saffa Heights, 38 floors on Dubai Creek | English with Arabic, AED with the exact dollar price, DLD Trakheesi permit + QR |
| Dock (UK / anywhere) | Lantern Wharf, 26 floors in Docklands | GBP, internal area, reservation fee, New Homes Quality Code |
| Ridge (India) | Sahyadri Vista, 30 floors facing the Baner hills | INR in lakh / crore, RERA carpet area, Hindi, MahaRERA registration + QR |
| Courtyard (Saudi) | مساكن دار النخيل, 14 floors in Al Malqa | Arabic first and right-to-left, SAR, REGA / Wafi licence + QR |
- A complete demo for each look you can import into a fresh WordPress with one command (homes, payment plan, milestones, posts, menus, the enquiry form and the field group).
- The
wpcommand-line tool that connects the site, imports the demo, checks your WordPress (wp doctor) and sets up the change notifications. - A region pack for 11 markets: tax lines, consent banners per law, accessibility statements, regulator blocks.
What it needs
- WordPress 6.7 or newer (tested on 7.1) with WooCommerce and a few free plugins — listed in Getting started. No theme code runs in WordPress and nothing is written in PHP.
- Node.js 20.9 or newer (22 or 24 LTS recommended) to run and build the website.
- Any host that runs Next.js (Vercel, Netlify, your own Node server). WordPress stays on its own host.
Getting started
About 20 minutes if WordPress and WooCommerce are already installed.
1. Install the free plugins
In wp-admin, Plugins → Add New, install and activate:
| Plugin | Needed | What for |
|---|---|---|
| WooCommerce | Required | Homes are products: price, stock = available / sold, the reserved tag |
| WPGraphQL | Required | The content the website reads |
| Secure Custom Fields (or ACF PRO) | Required | The development's fields (tower, timeline, payment plan…) |
| WPGraphQL for ACF | Required | Those fields in the content API |
| Yoast SEO + Add WPGraphQL SEO (or Rank Math) | One of them | Titles, descriptions, schema, sitemap |
| Contact Form 7 | Recommended | The "Register interest" form |
| Flamingo | Recommended | Keeps every enquiry in wp-admin, even when WordPress can't send email |
2. Create an application password
Users → Profile → Application Passwords — name it after your website, press Add, copy the password (it is shown once). Use an Administrator account.
3. Install and connect the website
In the project folder:
npm ci
node wp/wp.mjs connect --url https://cms.yourdomain.com --user <an Administrator> --app-password "xxxx xxxx xxxx xxxx" --site http://localhost:3000connect writes .env.local (keep it private; never commit it) with the connection and the kit's own settings (which content to keep in sync, the shop's filters).
4. Import a demo (optional)
Into a fresh WordPress, one look: dubai, london, pune or riyadh.
node wp/wp.mjs import ./demo/dubai --admin-password "your wp-admin password"It creates the field group, the development, every home, the payment plan, posts, menus and the enquiry form, and records that form as the site's enquiry form (WP_FORM_ID). Safe to run twice. Your wp-admin password is used once, for the field-group import form, and is not stored. Using your own content instead? Create a Contact Form 7 form and set WP_FORM_ID in .env.local to its number.
5. Connect the notifications and check
node wp/wp.mjs webhooks setup
node wp/wp.mjs doctorwebhooks setup lets WooCommerce tell the website about changes, so prices and stock update within seconds. doctor then shows a green row for WordPress, WooCommerce, every plugin, the content API, the cart and the enquiry form; a red row says exactly what to fix.
6. Run it
npm run devOpen http://localhost:3000. When you are happy: npm run build && npm start runs the production build.
Just looking? WP_FIXTURES=1 npm run dev runs the site on the bundled demo data, without a WordPress (NEXT_PUBLIC_KIT_PRESET=london for another look).
The pages
- Home — the site hoarding (name, from-price, the featured home, the regulator permit), then the construction calendar: scroll and the building rises floor by floor from launch to handover while the payment-plan ledger fills beside it ("Paid by then 20% · £149,000"). Stop on a floor and its homes unfold into cards. Then homes by type, Inside (the development's story and amenities), construction progress and Register interest.
- Residences (
/shop) — every home, filtered by availability, type, view and floor band; the building beside the list lights the matching windows. The count is your store's own count. Filters live in the address, so a filtered list can be shared. - A home (
/product/<home>) — a spec sheet: plan, where it sits in the building, size, floor, view, its own payment schedule, the buying costs and Enquire — plus Reserve when you take a reservation fee online. Homes are sold by your sales team, never through a basket. Anything else you sell (parking, storage, upgrade packs) gets a regular product page with Add to basket. - The development (
/development/<project>) — story, the drawing, facts, payment plan, amenities, sales office and permit. - Progress (
/progress) — the milestones and your "Construction updates" posts. - Basket, checkout, order — for reservation fees and other products: your store's own payment methods, or a hand-off to WooCommerce's checkout page.
- Accessibility statement (
/accessibility) — written for your market; and any WordPress page or post at its own address.
Motion
The calendar scrubs with the scroll (smooth, no jumps). The opening draws the building once. With "reduce motion" switched on, the site shows today's state with a floor chooser and nothing moves by itself.
Your content in WordPress
Everything the website shows is edited in wp-admin. Nothing is typed into the code.
The development — Developments → your project
| Tab | Fields |
|---|---|
| Project | Name in your second script (Arabic / Devanagari), tagline (both scripts), city, district, address, latitude / longitude, the WooCommerce category that holds its homes |
| Regulator | Regulator (DLD / RERA, Saudi REGA, MahaRERA, none), permit or registration number, registry link, the regulator's QR image exactly as issued, legal note |
| Tower | Floors, podium floors, homes per floor, floor height, footprint, crown, setbacks — the drawing redraws itself from these numbers |
| Timeline | Launch date, handover, construction %, milestones (date, floor reached, done) |
| Payment plan | Instalments by booking / months / construction % / handover (must add up to 100%), reservation fee on/off and amount, reservation agreement link, cooling-off days, refund rule, buying costs shown under every price |
| Amenities | Name (both scripts), floor, icon (icons show once every amenity has one) |
| Look | Look (Creek, Courtyard, Ridge, Dock — or Automatic, from the store's country), Inside picture and caption, the wording for a home's area ("Internal area", "RERA carpet area"…) |
| Sales | WhatsApp, phone, email, sales office — every button uses this one WhatsApp number |
Homes — WooCommerce → Products
One product per home: the price; stock 1 = for sale (a lit window), stock 0 = sold (an unlit window), the tag reserved = reserved (a hatched window, whatever the stock); the attributes Unit type, View, Floor, Bedrooms and Area; the plan image. Number homes floor + position (1201 = floor 12, first home) — the SKU carries that number. The short description shows under the home's name.
Everything else
- Name, language, store country and currency — Settings → General and WooCommerce → Settings → General. Arabic turns the whole site right-to-left.
- Logo, tab icon and menus — Appearance → Editor → Site logo; Settings → General → Site Icon; a navigation menu named "Primary" fills the header and one named "Footer" the footer.
- Site diary — posts in the category "Construction updates".
- Enquiries — the Contact Form 7 form "Register interest": its recipients and mail settings apply. With Flamingo every enquiry is also kept under Flamingo → Inbound messages; without it, an enquiry WordPress can't email is kept as a private post under Posts → Enquiries. No lead is lost.
- Reservations — Payment plan tab → "Take a reservation fee online". Available homes then show Reserve; the buyer pays the fee on the site by bank transfer (write your bank details in the Instructions of WooCommerce → Settings → Payments → Direct bank transfer: the thank-you page shows them with the order number as the reference) or cheque — never cash on delivery — after accepting your terms, and the home is tagged
reservedwith stock 0 at once. To release a reservation, remove the tag and set the stock back to 1.
Troubleshooting
wp doctor: "Application password" fails with HTTP 401. WordPress only accepts application passwords over HTTPS (local sites excepted), and some security plugins block them. Use the https:// address, allow application passwords / Basic auth for /wp-json/ in your security plugin, and create a new password for an Administrator.
I changed something in wp-admin and the site still shows the old version. Changes show within about ten seconds. If they never do, run node wp/wp.mjs webhooks setup again (did the site's address change?) and check the "Woo webhooks" row in node wp/wp.mjs doctor.
Enquiries arrive in wp-admin but nobody is emailed. WordPress sends email with PHP mail, which many hosts block. Install an SMTP plugin and send its test email. Nothing is lost meanwhile: enquiries are kept under Flamingo → Inbound messages (or Posts → Enquiries).
The site says "WordPress isn't connected". Run node wp/wp.mjs connect … — it writes .env.local. To look around without a WordPress, start with WP_FIXTURES=1 npm run dev.
The building drawing doesn't match my tower. It is drawn from the Tower tab (floors, podium, homes per floor, setbacks, crown). Homes are placed by their number: 1201 = floor 12, first home. Check the SKUs of homes that land on the wrong floor.
A window stays dark although the home is for sale. Its stock must be 1 and it must not carry the reserved tag; sold = stock 0.
npm run build fails with odd "NODE_ENV" errors. Your terminal sets NODE_ENV to something other than production. Clear it for the build: env -u NODE_ENV npm run build.
Accessibility
- Built to WCAG 2.2 AA: Lighthouse accessibility 100 on every page we test (home, residences, a home) on all four looks, phone and desktop.
- Windows are told apart by glow, hatching and fill plus a word — never colour alone.
- Every home is reachable by keyboard from the floor cards and the list; the gallery tabs follow the arrow keys; focus is always visible.
- "Reduce motion" shows today's state with a floor chooser; nothing moves by itself.
- Arabic reads right-to-left by design (not mirrored English); numbers and prices keep their order.
- The site publishes an accessibility statement for your market at
/accessibility— set your contact (WP_A11Y_CONTACT) and review date (WP_A11Y_REVIEWED) in.env.local.
Licence and support
- Licence — one licence for unlimited sites, personal or commercial (see
LICENSE.txtin the download). - Updates — new versions on your Pulse account page; your content stays in WordPress, so updating the website never touches it.
- Support — write to us from your Pulse account with what you ran and the last lines from the terminal, plus the output of
node wp/wp.mjs doctor.
Going live
- Host the website on any platform that runs Next.js. On Vercel: put the project in a private Git repository, import it at vercel.com/new and deploy. On your own server:
npm ci && npm run build && npm startbehind a web server for HTTPS. - Give the host your settings — every line of
.env.local(on Vercel: Project → Settings → Environment Variables). They hold the WordPress address, the application password and the site's secrets. - Point the kit at the live address and re-create the notifications: ``
node wp/wp.mjs connect --url https://cms.yourdomain.com --user <an Administrator> --app-password "…" --site https://www.yourdomain.com node wp/wp.mjs webhooks setup`` - Keep WordPress on its own address (for example
cms.yourdomain.com) and stop search engines indexing it there (Settings → Reading → "Discourage search engines"), so only the new site is found. - Check once more:
node wp/wp.mjs doctoragainst the live WordPress — every row green. - Email: install an SMTP plugin (WP Mail SMTP, FluentSMTP…) and send its test email, so the sales team is emailed about every enquiry.
Markets and legal
The site follows your store's country (WooCommerce → Settings → General → Store address) — 11 markets: EU, UK, US, Canada, Australia, UAE, Saudi Arabia, Gulf, India, Southeast Asia and international.
- Prices — your store's own currency, symbol and separators; Indian numbering (₹1,35,00,000 · ₹1.35 Cr); the exact dollar price for currencies pegged to it (AED, SAR, QAR…); price per area.
- Buying costs — shown under every home's price from the Payment plan tab (the 4% DLD fee, Stamp Duty Land Tax, stamp duty and registration…). Homes never show a shop's VAT line.
- Regulator — DLD Trakheesi, REGA / Wafi and MahaRERA blocks with the regulator's own QR image, on the home page, the development page, every home and the footer.
- Consent — a cookie notice that follows the law of the market: opt-in with equal Accept / Reject in the EU, UK, India (with your grievance officer), Gulf and Southeast Asia; notice + "Do not sell or share" in the US (Global Privacy Control honoured); notice + choice in Australia. Nothing optional runs before a choice.
- Accessibility statement —
/accessibility, written for your market (EAA, ADA, AODA…), with your contact. - Languages — English, Arabic (right-to-left) and Hindi for every word the kit itself writes; your content is in whatever language you write it.
- Saudi orders — the ZATCA QR on order pages when your seller VAT number is set.
Single features can be switched off with WP_REGION_OFF in .env.local (see .env.example).