AstroCorporate Website

terrasuite-emdash — Astro Business Template

By havenswift-hosting

An EmDash website template for estate agencies, including a property collection, a search page with filters, and the basic pages an agency needs on its first day.

Explore the design

Compare the page layouts and mobile experience. Open any screenshot for a closer look.

1 previews
Author preview
Author-provided previewTop of page

Preview provided in the project README.

One original preview is available. Open the full image to inspect the design.

Screenshots show visual appearance; interactive behavior may differ.

Recorded 2026-10-08View source

What stands out

A quick read of the recorded project description.

01

Includes a property collection, location taxonomy, menu, and a seed script that can generate any number of sample properties

02

The search page supports range filters such as price range and number of bedrooms; filter state persists after refresh and the URL is shareable

03

Provides the pages an agency needs on its first day, including homepage, search results, property details, and area aggregation pages

04

Search reads the collection data table directly, and a script to install indexes is included to improve query efficiency

05

Single CSS file, no framework, no web fonts, no requests to external hosts, colors controlled by two custom properties

Template Details

This is an estate agency website template made by Havenswift Hosting for EmDash (Cloudflare's CMS), built with Astro. The template provides a property collection (27 fields, location taxonomy, menu), a homepage, a search results page, property detail pages, and area aggregation pages, along with seed scripts and demo data loading scripts. The search function reads the collection data table directly to support range filters such as price range and number of bedrooms, because EmDash's content API does not have range operators. The template does not include map search, and the seed data does not include photos; agencies need to upload their own via the media library. The styling is a single CSS file, with no framework, no web fonts, no requests to external hosts, and colors controlled by two custom properties.

AstroCorporate Website

Is it right for your project?

Use Cases

  • Estate agencies quickly building an official website with property listings and filtered search
  • Property websites that need to filter listings by conditions such as price range and number of bedrooms
  • Website projects that want to use EmDash as a content management backend and customize the frontend display

Suitable For

  • Developers or teams using EmDash who need an estate agency website template
  • Estate agencies that need a property collection, search filters, and area aggregation pages
  • Projects that want to do secondary development based on Astro and EmDash

Getting started & customization

Use these recorded setup notes alongside the repository instructions for your chosen version.

  1. 1

    The template can be obtained from the GitHub repository via npm create astro or npx giget; npm create emdash cannot directly obtain this template

  2. 2

    The schema is applied on first request; afterwards run node scripts/install-indexes.mjs ./data.db to install search indexes and restart

  3. 3

    The seed data contains 24 properties covering 15 towns; more can be generated with npm run seed or node scripts/load-demo-stock.mjs

  4. 4

    When deployed behind a proxy, EMDASH_SITE_URL must be set to the origin accessed by the browser, otherwise image URLs will be written with the internal address

  5. 5

    The seed does not include photos; you can import your own JPEG images with scripts/load-demo-photos.mjs --from <folder>

Read repository instructions

License & source material

Usage conditions & limitations

Free to use · keep license notice

This entry covers the free version under the MIT license in the public repository; the free scope is the code of this version and does not mean that external services or third-party assets are free.

Must comply with when using

  • Free use, modification, commercial use, and distribution of this version's code are permitted.
  • When distributing copies or substantial portions of the code, retain the original author's copyright notice and the full MIT license notice.
  • The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.

Additional costs & items to verify

  • Demo images, fonts, icons, and other third-party assets must be checked against their respective licenses; they cannot be judged solely by the code's MIT license.
  • External services such as domain, hosting, database, payment, or AI may incur additional charges.
  • The template itself does not provide map search functionality; distance queries exist only in measurement scripts, and if a map is needed, you must choose and integrate a tile source yourself.
  • The seed data does not include photos; agencies need to upload their own via the media library; when a property has no photo, the card displays a placeholder panel instead of an image.
  • The template cannot be obtained via npm create emdash; instead use npm create astro or npx giget to install from the GitHub repository.
  • When deployed behind a proxy, EMDASH_SITE_URL must be set to the browser-accessed origin, otherwise image URLs will be written with the internal address.
  • You must run scripts/install-indexes.mjs to install search indexes, otherwise search performance will drop significantly.
View Original Text Basis

Permission is hereby granted, free of charge

Original License Text

No map search in the template. The distance query is in the measurement scripts and costs 0.097 ms at agency scale, but a map needs tiles, and which tile source an agency uses is their decision rather than ours.

Original README

No photographs in the seed. An agency uploads its own through the media library; until a property has one, the card draws a placed panel naming the property type rather than a broken image.

Original README

`npm create emdash` cannot fetch this: its template list is four names compiled into the package, so it only installs Cloudflare's own.

Original README

Set `EMDASH_SITE_URL` to the browser-facing origin. Behind Apache, nginx or a tunnel the app only ever sees the internal request URL, so without it EmDash writes `http://127.0.0.1:4321/...` into the `src` and `srcset` of every image its own `<Image>` renders.

Original README

Without the indexes in `scripts/install-indexes.mjs` the same search is 4.0 ms at 20,000, so run it.

Original README
https://github.com/havenswift-hosting/terrasuite-emdash/blob/main/LICENSEhttps://github.com/havenswift-hosting/terrasuite-emdash/blob/main/README.md

Compiled by DeepSeek based on repository license and README ·2026-10-08. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.

Project checks & description sources

Template Information

Source platforms
GitHub
Documentation and maintenance reference score
More documented · 83 / 100
Technologies
Astro
Website type
Corporate Website
How this score is calculated

Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.

What to verify for this project

Repository update recorded
2026-09-29
Screenshot last checked
2026-10-08

A demo link is listed. Check it with your own content and viewport sizes; its presence does not confirm that forms, authentication or payments work.

The catalog identifies Astro as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.

Use a selection guide →

How this description was prepared

AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.

Review declaration: [email protected] · 2026-10-08

Inspect the recorded source material

SHA-256: 35eba8d1d311e86d146e3ce68fe2df4471e8e7301c27b2f794fdef1683721d7e

2026-10-08T06:26:57.117Z

Source file / repository
# TerraSuite for EmDash

An estate agency site template for [EmDash](https://emdashcms.com), Cloudflare's
CMS. A property collection, a search that answers the question a buyer actually
asks, and the pages an agency needs on its first day.

Built by [Havenswift Hosting](https://www.havenswift-hosting.co.uk/), who make
TerraSuite for WordPress and have run hosting for United Kingdom businesses
since 2005.

**[Live demo](https://emdash.terrasuite.uk/)** - 420 properties, the real thing
rather than a video.

[![The home page](screenshots/home.png)](https://emdash.terrasuite.uk/)

## What is in it

| | |
| --- | --- |
| `seed/makeseed.py` | The property collection: 27 fields, a location taxonomy, a menu, and as many sample properties as you ask for |
| `src/pages/index.astro` | Home page: one search, the newest stock, every town |
| `src/pages/search.astro` | Results, with filters that survive a page reload and a shareable URL |
| `src/pages/property/[slug].astro` | A property, read through EmDash's own content API |
| `src/pages/area/[slug].astro` | Everything on the books in one town |
| `src/lib/property-search.ts` | The search itself |
| `scripts/install-indexes.mjs` | The indexes the search needs |

One stylesheet, no framework, no webfont, nothing fetched from another host.
Colour is two custom properties, so rebranding is two lines.

## Getting started

```sh
npm create astro@latest my-agency -- --template havenswift-hosting/terrasuite-emdash
cd my-agency
npm run dev
```

The schema applies on the first request. Then put the search indexes in and
restart:

```sh
node scripts/install-indexes.mjs ./data.db
```

The site is on `http://localhost:4321/` and the admin panel is at
`/_emdash/admin`.

`npm create emdash` cannot fetch this: its template list is four names compiled
into the package, so it only installs Cloudflare's own. Anything that reads a
GitHub repository will do instead, and `create-astro` hands any template
containing a `/` straight to [giget](https://github.com/unjs/giget), so this
works too:

```sh
npx giget@latest gh:havenswift-hosting/terrasuite-emdash my-agency
```

### Sample stock

`seed/seed.json` carries 24 properties across 15 towns, which is enough to see
the search work. For more:

```sh
npm run seed                 # regenerate the seed, any number of properties
node scripts/load-demo-stock.mjs 420   # or load straight into an existing database
```

### Putting it behind a proxy

Set `EMDASH_SITE_URL` to the browser-facing origin. Behind Apache, nginx or a
tunnel the app only ever sees the internal request URL, so without it EmDash
writes `http://127.0.0.1:4321/...` into the `src` and `srcset` of every image
its own `<Image>` renders. The search results still look right, because the
cards build their own URLs, so this shows up on property pages alone and is
easy to miss.

```sh
EMDASH_SITE_URL=https://www.your-agency.com node ./dist/server/entry.mjs
```

Photographs are not in the seed. `scripts/load-demo-photos.mjs --from <folder>`
puts a folder of JPEGs into the media library and hands them out by property
type, which is how the demo site above is dressed.

## The search, and why it is not the content API

`getEmDashCollection()` filters by field values or taxonomy terms. It has **no
range operator**, so "between 150,000 and 600,000" and "at least three bedrooms"
cannot be asked at all. A sandboxed plugin's `ctx.storage.query()` has ranges
but only on declared indexes, with one sort, 100 rows a page, and no way to ask
whether a multi-valued field contains a value.

So the search reads the collection table directly, which trusted site code may
do. EmDash has already done the hard part: every collection gets a real SQL
table with a real column per field, which is the same flat index TerraSuite
builds for itself on WordPress.

`/search?engine=api` runs the same page through the content API instead, and
says which filters it had to drop. It is there because the difference is worth
seeing rather than being told about.

![Search results](screenshots/search.png)

## What it costs

Measured on a real installation, ten filters, ordered by price, first page:

| Properties | Median |
| ---------- | ------ |
| 1,000 | 0.015 ms |
| 5,000 | 0.053 ms |
| 20,000 | 0.092 ms |
| 50,000 | 0.226 ms |

Without the indexes in `scripts/install-indexes.mjs` the same search is 4.0 ms
at 20,000, so run it. It takes 291 ms over 50,000 rows.

## What it does not do

No map search in the template. The distance query is in the measurement
scripts and costs 0.097 ms at agency scale, but a map needs tiles, and which
tile source an agency uses is their decision rather than ours.

No photographs in the seed. An agency uploads its own through the media
library; until a property has one, the card draws a placed panel naming the
property type rather than a broken image. `scripts/load-demo-photos.mjs` will
dress a demo with a folder of your own JPEGs.

## Licence

MIT, the same as EmDash.
Report a correction

Explore similar templates

Compare previews and descriptions within the same stack and category.