{"id":"ex3tvywdimw7ejb","title":"Mock-First Handoffs Before a Third-Party MLS Widget Ships","slug":"mock-first-handoff-before-mls-integration","summary":"I ship luxury real estate UIs with mock listing data first so design and Core Web Vitals stay proven before a startup MLS search widget lands.","imageUrl":"https://briancrabtree.me/images/journal-mock-first-handoff-before-mls-integration.webp","category":"Performance","date":"2026-06-06T18:00:00.000Z","featured":false,"likes":17,"author":"Brian Crabtree","content":"<h2>Why I mock the boundary first</h2>\n\n<p>A mock-first integration handoff is how I ship luxury real estate funnels when the UI has to be fast today and a startup MLS search widget arrives later. The product timeline rarely lines up. Stakeholders need to judge layout, photography, neighborhood context, and lead capture before anyone signs a feed contract. Waiting on live IDX data turns the front-end into a blocker instead of an asset.</p>\n\n<p>I treat the search widget as a bounded adapter, not the spine of the architecture. The React shell owns navigation, typography, listing cards, property detail routes, broker profiles, and forms. Mock data mirrors production shape—IDs, price fields, photo arrays, featured filters—so mappers stay honest when the real feed plugs in. You get a demo that behaves like the finished product without pretending the integration already happened.</p>\n\n<p>That discipline matters on mobile. Luxury buyers compare photos and price in seconds. If the handoff depends on a third-party script landing on the critical path before you can show inventory, you are betting conversion on someone else’s release calendar. I ship what I control first, prove speed, then wire the widget into a slot that was designed for it.</p>\n\n<pre><code>- [ ] mock-listings.json mirrors feed field shape\n- [ ] search surface isolated from layout shell\n- [ ] no vendor scripts on first paint\n- [ ] PSI mobile saved with URL before widget merge\n- [ ] forms work with mock success handlers</code></pre>\n\n<h2>What the handoff actually ships</h2>\n\n<p>The deliverable is a self-contained demo engine: listing grid, featured inventory, property detail views, market commentary blocks, broker roster, and contact flows wired to local mock JSON. Search and filter UI render real states—empty, loading, results—without calling a live MLS endpoint. Stakeholders scroll, tap, and submit forms the way they will after integration.</p>\n\n<p>On a recent luxury Pacific Northwest funnel I white-labeled the demo at <a href=\"https://briancrabtree.me/highline/\">briancrabtree.me/highline/</a>. Listing imagery is self-hosted WebP. Hero media reserves dimensions so layout stays stable. Forms return success states locally so design reviews are not blocked by cross-origin endpoints or credential setup that belongs in a later sprint.</p>\n\n<p>The handoff package includes typed listing mappers, featured filters, deploy scripts with basename support for subpath hosting, and a brand scrub gate that fails publish if forbidden MLS chrome slips back into the bundle. You are not receiving a theme zip and a prayer. You are receiving a measured front-end with a documented integration boundary.</p>\n\n<h2>Architecture choices that keep speed</h2>\n\n<p>The stack is deliberate: React 19 functional components, flat local state, vanilla CSS with design tokens—no UI kit skin, no runtime CSS-in-JS tax, no Tailwind ceremony on a site that needs a light DOM footprint. Every route is built to paint fast on mobile and stay keyboard-clean without a framework dictating the markup tree.</p>\n\n<p>Assets stay on origin. Hero and listing photos ship as compressed WebP with explicit width and height. Hero video stays off the critical path on mobile. JavaScript splits by route where it helps, but the bigger win is refusing render-blocking third-party search scripts until the core shell is stable. Autoplay video and “drop in the vendor widget and fix perf later” are the same category of mistake in my book.</p>\n\n<p>The lab result on the demo handoff was 98/100 mobile PageSpeed with strong Core Web Vitals headroom—not a promise that every future run will read 98 forever, but evidence that the architecture earned its budget before any MLS widget loaded. LCP came from a static hero and self-hosted media. CLS stayed near zero because media had reserved space and layout chrome did not inject late.</p>\n\n<h2>Where the MLS widget plugs in</h2>\n\n<p>Integration starts with a defined adapter region inside the inventory experience. The React shell keeps layout, navigation, and listing presentation. The startup MLS search widget mounts into that region through an interface the handoff documents—search query in, normalized listing records out. The UI does not surrender the page chrome to vendor markup.</p>\n\n<p>Mock data flows through the same mappers the live feed will use. When `mock-listings.json` supplies featured tags, price, beds, baths, and photo URLs, the components do not care whether the source was static or remote. That swap is a data problem, not a redesign. Search autocomplete, results pagination, and filter chips already have states; the widget replaces the mock fetch, not the component tree.</p>\n\n<p>I defer widget hydration until the shell has painted. Idle-friendly patterns and explicit mount targets keep the widget off the LCP path. If the vendor needs a synchronous bundle on first load, that is a negotiation with numbers attached—not a silent acceptance that tanks the funnel you already validated.</p>\n\n<h2>What stays off the critical path</h2>\n\n<p>Not everything belongs in the first second. Market ledger feeds, secondary analytics, map tile providers, and chat widgets can wait until the hero and primary inventory grid are stable. The handoff lists what is mocked, what is deferred, and what requires a compliant feed before it goes live on production hostnames.</p>\n\n<p>Forms on the demo use mock success handlers so UX reviews do not depend on CRM webhooks or spam filters being configured. MLS disclaimers, board-specific chrome, and credential-bearing endpoints stay off the public demo surface until legal and compliance sign off. That is not hiding complexity—it is sequencing work so design and speed do not wait on paperwork.</p>\n\n<p>Deploy automation enforces the boundary. A white-label patch pass rewrites asset paths for subpath hosting. A scrub step rejects bundles that reintroduce forbidden IDX artifacts. The demo proves the product experience; integration becomes adapter work with a checklist, not a rewrite of the performance budget you already measured.</p>\n\n<h2>How I prove speed before integration</h2>\n\n<p>I run PageSpeed Insights on the actual demo URL with mobile and desktop profiles and save the analysis link. I read LCP, CLS, and main-thread audits—not the headline integer alone. I scroll on a phone, submit forms, and navigate listing detail routes to confirm the mock data path feels fast in the field, not just in the lab.</p>\n\n<p>Before any third-party search script merges, I compare waterfalls with and without the widget on a staging hostname. If the widget must load synchronously, we document the cost and decide together. If it can lazy-load into the adapter region, we keep the validated shell intact. That is the same discipline I describe in <a href=\"/journal/performance-checks-before-handoff/\">Performance Checks Before Handoff</a>—reproducible runs, honest limits, no mystical quality labels.</p>\n\n<p>Regression checks repeat after content pushes. A new hero upload, an analytics snippet, or an approved widget update each get a fresh pass. Performance is not a one-time checkbox on handoff day. It is a contract about what stays off the critical path and who owns the script budget when integrations land.</p>\n\n<h2>What I do next</h2>\n\n<p>Open the demo at <a href=\"https://briancrabtree.me/highline/</a>, run your own mobile PageSpeed pass, and read the listing detail and search flows. Compare the mock inventory shape to what your MLS feed will supply. If the adapter boundary makes sense for your timeline, the integration work is bounded instead of open-ended.</p>\n\n<p>When you are planning a similar handoff—luxury funnel, third-party search widget on the roadmap, speed non-negotiable on mobile—<a href=\"/contact?ref=journal-handoff\">send a brief</a> with your URL, your integration timeline, and what feels slow today. I will tell you whether mock-first is the right cut, or whether you need a different sequence. No vendor names required on the first call.</p>\n\n<p>The goal is simple: ship the asset you control, prove design and Core Web Vitals with mock data, and plug the startup MLS search widget in when it is ready—not before the funnel has earned its speed.</p>","tags":["mock-data","react","handoff","core-web-vitals","third-party-integration"],"views":50}