Rebuilding a Real Estate Website for a Mobile-First Market
How I led the migration of a 2,000-listing real estate site from a vendor template to Astro SSG on Cloudflare's edge — cutting page weight by 96%, increasing organic traffic 35%, and shipping an AI assistant that changed how buyers evaluate properties.
TL;DR — Nearly 74% of our real estate site’s traffic was mobile, but the site was built for desktop. Microsoft Clarity showed visitors bouncing with zero interaction, and Cloudflare data confirmed most were on bandwidth-limited mobile carriers. I led the full product strategy and migration to an Astro static site on Cloudflare’s edge — zero API calls at load time, 96% lighter pages, responsive images everywhere. Early results: 35% more organic traffic, 37% more lead submissions, and an AI assistant that gives buyers instant property opinions they actually use.
The Website Was Losing Customers Before They Saw a Single Listing
In early 2023, Styllus Imobiliaria went through a rebrand. New visual identity, new positioning, new energy. But the website stayed the same — a well-customized template from our property listing syndication partner, originally migrated around 2019-2020. I was the product and technical lead for the website, responsible for all product strategy, architecture decisions, and vendor coordination while working with outsourced developers on implementation.
By late 2025, the mismatch between the brand and the digital experience was impossible to ignore. But the cosmetic gap was not the real problem. The real problem was in the data.
Mobile traffic had shifted dramatically. When the template was adopted, roughly 35% of visitors came from mobile devices. By February 2026, that number was 73.7% — smartphones alone accounted for 69.4%, with another 3.8% from phablets. Desktop had shrunk to 26.3%. The website had been designed for a desktop-majority audience that no longer existed.
Microsoft Clarity told the rest of the story. Session recordings showed a pattern: visitors would land on a listing page, wait, and leave. Many sessions showed zero interaction after the page loaded — not even a scroll. Others lasted only a few seconds. The bounce rate on mobile was high, and it was rising.
When I cross-referenced this with Cloudflare IP data, the picture got worse. Most of our mobile visitors were on Brazilian mobile carriers with significant bandwidth limitations. They were not just on small screens — they were on constrained connections. We were serving a 20MB homepage to people on limited data plans.
The site had gone through rounds of adaptation — patches on top of a desktop-first template trying to approximate a mobile experience. Each fix addressed a symptom. None addressed the architecture.
The Hypothesis
If we rebuilt the site as a mobile-first static experience, pre-rendered and served from the edge with zero API calls at load time, we could reverse the bounce trend and convert the mobile traffic we were already getting but failing to serve.
The bet was specific: performance was not a technical nice-to-have but a direct conversion lever. Visitors on bandwidth-limited connections were not bouncing because our listings were bad. They were bouncing because the page never finished loading.
A secondary hypothesis drove a more ambitious feature: if we embedded an AI assistant on listing pages that could give buyers instant, unbiased property opinions, we could increase time on page and reduce the friction between browsing and contacting a realtor.
Why a Rebuild, Not a Renovation
Before committing to a full migration, I evaluated four alternatives.
Upgrading the existing PHP template was the lowest-risk option, but the vendor’s architecture imposed viewport limitations and required approval for structural changes. The template had accumulated years of adaptation layers. Each new patch added complexity without addressing the core issue: a desktop-first rendering model serving a mobile-first audience. The cost of continued patching was growing while the returns were shrinking.
WordPress offered a massive ecosystem and easy content management. I rejected it because we needed edge-served static files with zero origin calls at load time — WordPress’s server-rendered model was the opposite of that architecture.
Webflow would have solved the design problem quickly, but it limited our ability to build custom features like the AI assistant and template-based SEO landing pages. It also introduced a new vendor dependency for the core site.
Next.js was a strong contender — modern, React-based, good Cloudflare support. But we were already working on Cloudflare’s edge for other projects, and the goal was static files served from edge nodes with everything pre-built at deploy time. Next.js could do this but carried more JavaScript overhead than necessary.
I narrowed the static site generator field to Hugo, Jekyll, and Astro. Astro won because its islands architecture let us ship zero JavaScript by default — meaning the page would work on the worst connection we were designing for — while still supporting the interactive features the product required (AI chat, image gallery, contact form). Hugo and Jekyll could generate static sites, but neither offered Astro’s component model for selectively hydrating interactive elements without loading a full framework.
I wanted the website to be loaded with everything the customer needed at the point they needed it, with nothing else. Astro’s architecture was the only one that matched that product requirement without compromise.
Designing the Solution
The migration had three product-level objectives, each with a corresponding technical strategy.
flowchart TD
A["Product Objective"] --> B["1. Fast on Any Connection"]
A --> C["2. AI-Assisted Property Evaluation"]
A --> D["3. SEO-Compliant at Scale"]
B --> E["Astro SSG + Cloudflare Edge<br>Zero API calls at load time"]
C --> F["Stella AI Assistant<br>On every listing page"]
D --> G["Template-Based Landing Pages<br>Clean sitemap generation"]
Objective 1: Fast on Any Connection
The core product requirement was not “make it faster” — it was “make it usable for someone on a Brazilian 4G carrier browsing on a mid-range smartphone.” That framing changed every downstream decision.
The old site loaded 16 synchronous JavaScript files before rendering any content. It shipped 2.79MB of font files, 662KB of CSS, and 629KB of JavaScript on a single listing page. Total page weight for the homepage was over 20MB. For a user on a limited data plan, visiting three listings could consume a meaningful chunk of their daily allowance.
Every architectural decision started with the same question: does this make the page usable on a constrained connection?
- Visitors were bouncing before the page finished loading, so the page could not depend on runtime API calls. Every page is pre-rendered at deploy time and served as static HTML from Cloudflare’s edge — zero origin calls, zero wait.
- 16 synchronous scripts were blocking rendering before a single listing appeared. We flipped the default with Astro’s islands architecture: JavaScript loads only for the three components that genuinely need interactivity (chat widget, image gallery, contact form). Everything else ships as pure HTML and CSS.
- Mobile users on limited data plans were downloading the same 15MB of images as desktop users on fiber. Responsive images with Cloudflare Image Resizing now serve every image at the exact dimensions the viewport needs, in AVIF format.
- Font loading was consuming more bandwidth than actual page content — 2.79MB across six families, most of which were icon fonts. We replaced them with one variable-weight font at 57KB.
- 662KB of CSS was render-blocking every page load. Tailwind’s purged CSS build dropped that to 69KB.

Objective 2: Stella AI — Instant Property Opinions
The AI assistant hypothesis came from a counterintuitive user research finding. When I interviewed both realtors and potential buyers, I discovered that buyers loved to share listing URLs with brokers to get professional validation. They were not just browsing — they were seeking expert opinions on whether a property was worth pursuing. The friction was that getting a human opinion required reaching out, waiting, and navigating a social interaction before they were ready to commit.
Stella AI addresses this by providing instant, unbiased opinions directly on each listing page. The assistant can answer questions about the property, the neighborhood, and comparable listings. It includes a formula that calculates whether the property is priced below market value — the kind of insight buyers were previously seeking from brokers.
The product hypotheses were specific:
- Increase time on page — visitors who engage with Stella explore listings more deeply
- Reduce contact form friction — Stella answers preliminary questions that otherwise block the decision to inquire
- Competitive differentiation — no competitor in the market offers AI-powered property evaluation on listing pages
This also generates valuable data. Every question buyers ask reveals intent signals and common concerns that inform how we present listings. The conversation logs became an unexpected source of user research. Stella adoption data is still maturing — we are tracking conversation volume, engagement rate, and conversion influence, and will report those metrics as the dataset grows beyond the initial launch window.
Stella generating her property opinion from internal data and listing details in under 500ms
Objective 3: SEO-Compliant at Scale
The old site had a serious sitemap problem: 7,000 to 9,000 URLs for only ~2,000 actual listings. Duplicate URLs, stale links, and inflated page counts were diluting search authority and confusing crawlers.
Google Search Console revealed a compounding issue. Searches like “apartamento Méier,” “casa Tijuca,” and “comercial Rio” were generating 200-400 monthly impressions, but we ranked on page 3-4 for those intents and captured near-zero clicks — while competitors all had neighborhood and property-type landing pages capturing that volume. We had listing detail pages and nothing else. Every neighborhood search was a missed opportunity.
The new architecture generates a clean, accurate sitemap at build time — one URL per listing, no duplicates, no stale entries. We added JSON-LD structured data on listing pages (the old site had none), proper meta robots directives, and Twitter Card metadata for social sharing.
Beyond the sitemap cleanup, I built template-based SEO landing pages — pages targeting specific neighborhoods, property types, or search intents that could be edited by the team and built automatically during deployment. This gave us a scalable content strategy without requiring developer involvement for every new landing page.
What We Chose Not to Build
- A custom CMS. The syndication partner’s platform remains the source of truth for listing data. Building a parallel content management system would have created sync conflicts and doubled the editorial workload. The XML feed from the partner flows into the build pipeline directly.
- Client-side search. For 2,000 listings, a full client-side search index would add significant JavaScript weight — exactly what we were trying to eliminate. Search is handled through pre-built filter pages and the AI assistant.
- Analytics on day one. The old site loaded Google Analytics, Google Tag Manager, and a Facebook Pixel — contributing to the JavaScript bloat. We shipped without third-party analytics scripts, planning to add GDPR-compliant tracking as a fast-follow rather than blocking launch on it.
Execution and Rollout
The migration launched in January 2026, with full cutover in February. The rollout was not seamless — bulk URL rewrites during the migration caused a temporary dip in organic traffic in January as search engines re-indexed the new URL structure. This was expected and planned for: we set up proper 301 redirects and monitored Search Console daily until traffic recovered.
The outsourced development team handled implementation while I managed the product roadmap, architecture decisions, vendor coordination, and QA. I specifically hired developers with Astro and Cloudflare familiarity — that was a hard requirement, not a nice-to-have. I brought them on board early to build velocity while I was still running discovery, which was an intentional sequencing decision: the performance migration had clear technical requirements even before discovery finished defining the full feature scope.
The developers executed well — which created a productive tension. The team built faster than discovery could define boundaries, so the proof of concept naturally expanded beyond the intended scope. When discovery clarified the actual boundaries, I pulled back and re-scoped the sprint. No work was wasted, but the timeline stretched. If I could redo one thing, it would be accounting for how quickly a capable team outpaces incomplete requirements when discovery runs in parallel.
I wrote the PRD, broke work into tasks on a GitHub project board, and ran a 1-month sprint with 3 outsourced developers using a PR-based workflow with staging previews on Cloudflare Pages before production deployment. I wrote the performance benchmarking scripts myself — seven Node.js analysis tools covering DNS, HTTP headers, asset optimization, viewport testing, mobile 4G simulation, and redirect diagnosis — to validate that the migration met our performance targets before and after launch.
Early Results
The data is early — we are comparing February 2026 against February 2025, with the full migration completing in late January. These numbers will mature, and I will update this post as they do.
| Metric | Change | Notes |
|---|---|---|
| Organic traffic | +35% YoY | Feb 2026 vs Feb 2025 |
| Lead form submissions | +37% | Same period |
| Bounce rate | -10%+ | Decrease across all devices |
| Time on site | +25%+ | Strongest improvement on mobile |
| Page weight (homepage) | 20.79MB to 910KB | 95.7% reduction |
| Page weight (listing) | 25.26MB to 3.06MB | 87.9% reduction |
| Mobile 4G full load (homepage) | 11.3s to 1.27s | 88.8% faster |
| Mobile 4G LCP (listing) | 1.96s to 491ms | 74.9% faster |
| Mobile data cost per visit | R$0.014 to R$0.002 | 62-90% savings for users |
The January dip from URL rewrites recovered within weeks. The trajectory is strong, though I am cautious about attributing the full lift to performance alone — seasonal patterns, market conditions, and the new brand presence all contribute. The signal I trust most is the behavioral data: time on site up 25% and bounce rates down 10% point directly to the experience improvements.
Lessons and Reflections
Performance is a product feature, not a technical metric. It is easy to treat web performance as an engineering concern — something the dev team optimizes after the “real” product work is done. This project proved otherwise. The single highest-impact product decision was not a feature, a design choice, or a content strategy. It was the architectural decision to serve static files from the edge with zero JavaScript by default. That decision, more than any other, is what turned bouncing visitors into leads. The PM lesson I take forward: when your users are on constrained connections, performance is the product. Ship the lightest possible experience and add weight only when it earns its bytes.
User research reveals counterintuitive behavior if you let it. The discovery that buyers share listing URLs with brokers for validation — rather than just browsing independently — reshaped the entire AI assistant strategy. Stella is not a chatbot bolted onto a listing page. It is a response to an observed behavior: buyers want expert opinions before they are ready to talk to a human. Without those interviews, I would have built a generic FAQ bot. The transferable principle: never assume you know why users do what they do. Watch them, then ask them, and expect to be surprised.
Instrument before you migrate. Writing seven benchmarking scripts before cutting over was one of the best time investments of the project. Having quantitative before-and-after data across DNS, HTTP, assets, viewports, and simulated mobile connections meant I could validate every architectural decision against measurable outcomes — and catch the TTFB regression immediately. The lesson is broader than this project: if you cannot measure the current state precisely, you cannot prove the new state is better. Measurement is not post-launch analytics. It is pre-launch infrastructure.
What Comes Next
The immediate roadmap has one priority: personalized AI recommendations. As visitors browse multiple listings, Stella will correlate their viewing patterns and surface insights — “the apartment you viewed in Meier is 20% cheaper per square meter than this one in Tijuca, with more area.” This requires GDPR-compliant cookie tracking, which is why we did not ship analytics or personalization on day one. I am testing two presentation models: conversational recommendations within the chat interface, and a dedicated AI recommendation panel on listing pages.
The site migration solved the immediate problem: visitors can actually use the website. The AI layer is where the long-term differentiation lives — and the question now is not whether personalization will work, but which interaction model converts better.