An estate agency website built with EmDash and Property Web Builder, deployed on Cloudflare Workers.
Property listings, search, and enquiries come from the PWB Rails backend. Site content, blog content, admin UI, and editor workflows come from EmDash.
Live demo deployment:
- property search and detail pages powered by PWB
- EmDash-managed CMS pages and blog content
- EmDash admin UI for content editing
- a PWB properties admin plugin
- a PWB property embed plugin for inserting live listings into rich content
- a PWB valuation plugin workspace package
- MCP support via EmDash for AI-assisted workflows
- Cloudflare Workers deployment with D1 and R2
- Frontend: Astro
- CMS/admin: EmDash
- Listings backend: Property Web Builder (Rails API)
- Production runtime: Cloudflare Workers
- Production database: Cloudflare D1
- Production media storage: Cloudflare R2
- Local database: SQLite (
./data.db) - Local media storage: filesystem (
./uploads)
The split is intentional:
- PWB is the source of truth for listings and property search
- EmDash is the source of truth for editorial content and admin workflows
| Route | Purpose |
|---|---|
/ |
Homepage |
/properties |
Property search |
/properties/:slug |
Property detail |
/posts |
Blog archive |
/posts/:slug |
Blog post |
/pages/:slug |
CMS page |
/_emdash/admin |
EmDash admin |
/_emdash/api/mcp |
EmDash MCP endpoint |
- Node.js 18+
- pnpm 10+
- a running PWB backend
pnpm install
cp .env.example .envSet PWB_API_URL in .env, for example:
PWB_API_URL=http://localhost:3000Seed the local database:
npx emdash seed seed/seed.jsonPreferred development command:
pnpm devThis wrapper starts npx emdash dev --port 4444 and opens the dev-bypass admin URL
automatically.
Important local URLs:
- site: http://localhost:4444
- admin: http://localhost:4444/_emdash/admin
- admin bypass: http://localhost:4444/_emdash/api/setup/dev-bypass?redirect=/_emdash/admin
If you want the raw EmDash dev server instead of the wrapper, you can also run:
npx emdash devThat typically runs on port 4321.
pnpm dev # wrapper around emdash dev on port 4444
npx emdash dev # direct EmDash dev server
npx emdash seed seed/seed.json
npx emdash types
pnpm export:d1-sql
pnpm sync:prod-db
pnpm reset:admin-access
pnpm test
pnpm test:run
pnpm build
pnpm deployThis repo now contains several PWB-related plugin efforts:
- docs/pwb-properties-plugin.md Read-only PWB properties admin plugin.
- docs/pwb-properties-plugin-write-capable.md Planned write-capable architecture for listing editing.
- docs/pwb-properties-content-embedding.md Property embedding inside Portable Text content.
- docs/pwb-valuation-plugin.md Valuation plugin work.
This repository carries a local pnpm patch for emdash@0.1.0 so Portable Text plugin
blocks can persist arbitrary attributes during editor roundtrips.
That patch is tracked here:
Background and maintenance notes are documented here:
Use the Cloudflare deploy button above.
After deployment, configure the PWB backend URL:
wrangler secret put PWB_API_URLYou will also need to configure your real D1 and R2 resources in wrangler.jsonc.
pnpm build
pnpm deployIf you need to push the local SQLite CMS database into remote D1, use the repo script:
pnpm sync:prod-dbFor a preview without making changes:
pnpm sync:prod-db --dry-runRecommended "replace remote content with local content" flow:
pnpm sync:prod-db --backup --force-resetThat will:
- back up the current remote D1 database first
- clear remote table data
- import local data into the existing remote schema
If production admin access is lost because passkey state no longer matches the deployed DB, use:
pnpm reset:admin-accessThat backs up the remote auth/setup tables, clears admin login state, and reopens the setup flow at:
-
all rows in the affected auth tables are deleted, including all rows in
users -
https://emdash-property-web-builder.etewiah.workers.dev/_emdash/admin/setup
For production deploys, also review:
DBD1 bindingMEDIAR2 bindingPWB_API_URLsecret- optional
PUBLIC_PALETTEtheme var
- docs/development-guide.md
- docs/architecture.md
- docs/troubleshooting.md
- docs/admin-access-recovery.md
- docs/remote-content-and-mcp.md
- docs/product-roadmap.md
pnpm devandnpx emdash devare not identical in this repo.- changes to plugin registration or
astro.config.mjsusually require a full dev server restart emdash-env.d.tsis generated- PWB must be reachable for live property pages and property embeds to resolve fully