VidaMar: 1,700 listings, seven languages, no page builder
VidaMar sells resale homes, new builds and rentals on the Costa Blanca to Ukrainian-speaking buyers. We replaced their theme-based site with clean WordPress: our own data core, a feed importer, a lead inbox and a theme designed from scratch. Same URLs, every listing published, one week from concept to staging.
Listings migrated: 1,061 from the feed and 643 entered by hand
Feed photos re-encoded to WebP: 2.3 GB instead of 20+ GB
Languages, one page per listing, no duplicate content
Requests per page, down from about 200 with the old theme
Old URLs checked after the switch: every one kept or redirected
Catalogue query on the index table, facets in 36 ms
One agency, three catalogues, buyers in seven languages.
VidaMar’s site had grown around a paid theme: a daily feed of new builds, 640 resale listings typed in by hand, rentals mixed into sales, and Google-translated pages for Dutch, German, French, Italian, Spanish and Ukrainian visitors. It worked, but every limit of the theme had become the agency’s limit.
- Only 500 of 1,061 feed new builds were published, with 3 photos each.
- 388 resale listings sat on a default coordinate in Miami, so the map and radius search were wrong.
- The page builder and the theme loaded about 200 requests per page.
- 541 descriptions existed only in Spanish, and auto-translation left them half done.
- Publish everything from the feed automatically, with all photos, every day.
- Give visitors real filters, a map, a shortlist and a way to book a viewing.
- Keep every URL, speed the site up and make it fully multilingual.
- Leave the agency with a listing form it can use in a minute, not a page builder.
Real filters, not a theme’s search widget.
The catalogue is rendered on the server, so it ranks and works without JavaScript. Filters swap the results in place, keep the URL shareable and show live counts before you apply them.


City / area tree. 6 coasts, 83 towns and 291 areas with counts, searchable.

More filters. Distance to the sea, pool and features straight from the feed.

Price with presets. Type a range or pick one, then beds and baths.
Map or list, same filters.

- Leaflet with OpenStreetMap tiles: no Google Maps key, no per-view fees.
- Pins come from the site’s own REST endpoint and follow the active filters.
- Listings without an exact address show an approximate-location circle, never a false pin.
- List view for scanning prices and price per m² at a glance.

List view. The same cards, one per row, with the full description snippet.
Everything a buyer asks, on one page.
Gallery, facts, description, map, costs and a booking card that stays in view. Feed listings and manual listings use the same template.

- Gallery with a lightbox; the rest of the photos load only when opened.
- Price, €/m², built area, bedrooms, bathrooms, plot and distance to the sea.
- Description split into headings, amenities as icons, floor plans from the feed.
- Spanish-only texts machine-translated into English, with a “Show the original” switch.
- Running costs (IBI, community fees) shown per month.
- Similar properties and RealEstateListing structured data for Google.

Location. An exact pin when the agency has the address, otherwise a circle around the area.
A viewing booked in two steps, every lead in one inbox.
Most of VidaMar’s buyers are abroad when they choose, so the booking card offers a video call first and keeps the messengers one tap away.
- Step 1. In person or video call, a day from the next two weeks, a time slot in Madrid time.
- Step 2. Name, phone, email, message. The listing and the chosen slot travel with the request.
- Or faster via messenger. WhatsApp, Viber, Telegram and Messenger under every form.
- Consultation request. Preferred channel, goal and the best time to call, from any page.
- Days and months are written in the visitor’s language; prices and IDs are never translated.

Step 1 of 2. Format, day and time.

Step 2 of 2. Contact details, then a confirmation with the slot.


Enquiries inbox in wp-admin
Every form posts to the site’s own leads table and emails the agency. New requests are counted in the admin menu; each card holds the contact, the listing, the chosen viewing slot and notes, with statuses from new to done.
A honeypot field, a minimum fill time and a rate limit keep bots out. The history from the old CRM, 154 records, was imported so nothing was lost.
Favourites and comparison, without an account.
A heart and a scales icon on every card. Favourites stay on the device; compare puts up to four listings side by side with price per m², area, distance to the sea and features.

- “Send us the list” turns a shortlist into one viewing trip or a video call.
- The compare tray follows you through the catalogue; sold listings drop out on their own.
Seven languages from one page.
The switcher in the header and the mobile menu covers EN, NL, FR, DE, IT, ES and UA and the choice sticks between pages. Prices, reference numbers, phone numbers and place names are never translated.

- 541 Spanish-only descriptions were translated into English with DeepL; visitors can show the original.
- Feed listings keep their texts in 13 languages; the interface is translated on the fly.
Three small plugins instead of a page builder.
No paid theme, no page builder, no multilingual or forms plugins. The data lives in the site’s own tables, the theme reads them, and everything runs from the command line too.
- Kyero XML, 1,061 new builds
- Checked daily, 13 languages
- Up to 50 photos per listing
- Adopts, updates and retires listings
- Photos to WebP, ≤ 1,600 px, one file each
- Texts stored per language
- Property records and an index table
- Locations: coast → town → area
- Texts per language, REST API, WP-CLI
- Admin form: facts, gallery, map pin
- Catalogue, map, listing pages
- Favourites, compare, forms
- Sitemap, redirects, structured data
- Own leads table, inbox in wp-admin, email to the agency
- Honeypot, minimum fill time, rate limit
- Old CRM history imported
- Clean server, 4 cores / 8 GB
- Page cache friendly: no cookies on listing pages
- Migration kept every ID: 1,296 URLs unchanged, 575 old addresses redirected, none broken.
- Sitemap with 1,703 listings and 54 catalogue landing pages; JSON-LD, Open Graph, canonical.
- Resale photos re-encoded: 3.24 GB became 0.81 GB, one file per photo.
- Only our data travelled to the new server, nothing from the old install.
Filters in a sheet, booking in the thumb zone.
Most visits come from phones. Photos stay large, filters open as a full-screen sheet with counts, and the price with “Book a viewing” is pinned to the bottom of every listing.

Home. Search first, one column.

Catalogue. Photos first, filters one tap away.

Filters. Full-screen sheet with live counts.

Listing. Price and booking pinned to the bottom.