# Competitive Research: HOMEX (homex.ph) Clean-room reconnaissance of `https://www.homex.ph/`, conducted via `curl` (headers, HTML, robots.txt, sitemap.xml, `_next/static` JS bundles) and a real Chrome browser session (rendered DOM, live network calls). All public pages only; no auth bypass, no bulk scraping. Research date: 2026-07-11. ## 1. Overview & positioning HOMEX (`www.homex.ph`, page title "HOMEX — Condo Rentals in Metro Manila", footer copyright "HOMEX inc. © 2026") is **not** a classic property-listing portal like SUUMO — it is a **condo rental management SaaS** with a public listing micro-site bolted on as a lead-gen front end. This is stated explicitly in the app's own copy (pulled from the embedded i18n dictionary, `about.*` keys): > "HOMEX was born from a simple observation: managing rental properties in Metro Manila > is fragmented, paper-heavy, and stressful... We set out to build a single platform that > connects agents, landlords, and tenants in real time — automating rent tracking, > payment reminders, and communication." The product is built around a **four-role system**: Admin, Agent, Landlord, Tenant (`role.admin/agent/landlord/tenant` i18n keys), each with a dashboard covering rent tracking, lease documents, payment-proof upload/confirmation, agent commission tracking, in-app chat, and account management (all gated behind `/dashboard/`, `Disallow`'d in robots.txt and not directly observed). **Target users (inferred from copy):** Metro Manila condo landlords/owners and the agents who manage their units on their behalf, plus prospective tenants who browse the public listing pages. The language toggle is English/**Chinese (Simplified)** — not English/Filipino/Tagalog — suggesting a deliberate targeting of Chinese-speaking condo investors/landlords in Metro Manila (a well-known PH condo-investment demographic), not mass-market local renters. **Scale:** The about page claims "HOMEX powers condo rentals across 11 cities in Metro Manila... thousands of units" (`about.story3`), but the **live public data directly observed** is far smaller: 4 buildings returned by the buildings API (Makati, Pasay, Quezon City, Taguig) and 5 available units city-wide (see §3). This is a real marketing-copy-vs-live-data gap — treat the "thousands of units" claim as unverified (inferred marketing, not observed). **Ownership/parent company:** Not observed. A web search for "HOMEX homex.ph condo management Metro Manila company founder" returned no matches for this specific company (only unrelated companies sharing the name — a Mexican homebuilder, a US home-services firm, etc.). No funding/press coverage found. Appears to be an early-stage or pre-launch/demo-scale local product with no public profile yet. ## 2. Tech stack & architecture Concrete evidence from response headers and bundle inspection: - **Framework:** Next.js **App Router** with React Server Components. Evidence: `vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch` on `/`; `x-powered-by: Next.js` and `x-matched-path: /units/[id]` on the dynamic detail route; JS chunk naming (`app/layout-*.js`, `app/page-*.js`, `main-app-*.js`, `webpack-*.js`, `polyfills-*.js`) is the standard Next.js App Router build-manifest layout; `self.__next_f.push([1,...])` RSC flight-payload markers present in served HTML. No classic `__NEXT_DATA__` blob (confirms App Router, not Pages Router). - **Host/CDN:** **Vercel**, directly (no Cloudflare in front — no `cf-ray`/`cf-cache-status` headers observed). Headers: `server: Vercel`, `x-vercel-cache: HIT` (homepage, edge cached with `age: 57491`) vs `x-vercel-cache: MISS` and `cache-control: private, no-cache, no-store, max-age=0, must-revalidate` on `/units/2` (dynamic, uncached), `x-vercel-id: hnd1::...` / `kix1::iad1::...` (edge PoPs in Tokyo/Osaka + origin in `iad1`, i.e. AWS us-east-1 region for the Vercel deployment). `strict-transport-security: max-age=63072000` present. - **Images:** Next.js built-in Image Optimization (`/_next/image?url=...&w=...&q=75` URLs observed for `city-skyline.jpg`, `homex-logo.jpg`), default `loader` config (`imgix`, `cloudinary`, `akamai`, `custom` string literals found inside the shared JS chunk are just Next's built-in loader enum, not evidence Cloudinary is actually wired up — no live Cloudinary calls observed). - **Analytics/tag manager:** Google **gtag.js**, measurement ID `G-NDRSVM1GCM` (``). No other tag manager, no Hotjar/Segment/Mixpanel markers found in bundles (a stray string match on "segment" in the homepage grep was a false positive — not present in script sources). - **No map library detected** — no Leaflet, Mapbox, Google Maps JS API, or MapLibre strings anywhere in the shipped JS bundles (`_next/static/chunks/*.js`, ~394 KB combined across the 9 chunks pulled from the homepage). - **No auth-as-a-service vendor detected** — no Clerk/Auth0/NextAuth/Firebase Auth strings in bundles. The i18n dictionary has full custom login/register/forgot-password/ reset-password/change-password flows with "Demo Accounts:" label on the login screen and temporary-password-reset admin flow (`accounts.tempPassword`, `accounts.confirmReset`), consistent with a **hand-rolled email+password auth system** (inferred). - **No JSON-LD structured data anywhere** — checked homepage and a unit detail page, none found. Meta tags are **static and identical across all pages** (homepage, unit list, unit detail all serve the same generic `HOMEX — Condo Rentals in Metro Manila` and the same `og:description`) — per-listing dynamic ``/OG tags are **not observed**, i.e. not implemented. ## 3. Data layer & hidden APIs The site ships pure client-side data fetching: server-rendered HTML for `/units/[id]` returns only `<title>HOMEX......Loading...` — all listing data is fetched **after** hydration via `fetch()` calls embedded in the App Router client bundle (`app/page-26d1c79b0bcddfaa.js`). Confirmed by reading the deobfuscated bundle and by watching the real browser render: **Endpoints found (full paths, both directly curl-able and unauthenticated):** - `GET /api/public/buildings` — returns all buildings. - `GET /api/public/units?building_id=&city=&tower=&unit_type=&tags=&search=&status=` — returns units; the homepage's live filter bar calls this with `status=available` hardcoded plus whichever of `city`, `building_id`, `tower`, `unit_type`, `tags`, `search` the user has set (single-select each, from the bundle's `e.set("tower",C)`, `e.set("unit_type",_)`, `e.set("tags",R)`, `e.set("search",y.trim())` calls). Both are listed under `Disallow: /api/` in robots.txt (crawlers blocked) but are called directly by client JS in every page load and return plain JSON with **no auth check** — loading the site as a normal visitor triggers these exact requests. **Real response observed, `GET /api/public/buildings`:** ```json {"buildings":[ {"id":2,"name":"Makati CBD Apartment","city":"Makati","towers":"Tower A"}, {"id":5,"name":"MOA Bayfront Condo","city":"Pasay","towers":"Tower 1, Tower 2"}, {"id":4,"name":"Quezon City Townhouse","city":"Quezon City","towers":null}, {"id":1,"name":"BGC High Street Condo","city":"Taguig","towers":"Tower 1, Tower 2"} ]} ``` **Real response observed, `GET /api/public/units?status=available`** (one record, field names verbatim): ```json {"id":2,"building_id":1,"tower":"Tower 1","floor":"22F","area":65,"unit_type":"2BR", "unit_number":"22B","owner_name":"John Dela Cruz","owner_contact":"+63 918 234 5678", "owner_email":"landlord@homex.ph","monthly_rent":68000, "description":"Spacious 2-bedroom unit with balcony.", "images":"/uploads/units/twobr-living-01.png,/uploads/units/twobr-bedroom-01.png", "status":"available","created_at":"2026-07-07T12:45:18.684Z","tags":"balcony,split_ac", "building_name":"BGC High Street Condo","building_city":"Taguig", "building_towers":"Tower 1, Tower 2","agent_id":2,"agent_name":"Maria Santos", "agent_avatar":null} ``` **Noteworthy finding — unauthenticated PII exposure:** the public units endpoint returns `owner_name`, `owner_contact` (a real-looking PH mobile number format `+63 9xx xxx xxxx`), and `owner_email` for every unit, with no authentication and no redaction, to any anonymous visitor/crawler that hits the endpoint. This is the kind of data a listing portal normally keeps server-side and brokers through an agent-contact form. Flagging as an observed data-shape fact, not something we probed further. **Inferred field shape (listing/"unit" object):** `id, building_id, tower, floor, area (sqm, int), unit_type ("Studio"|"1BR"|"2BR"|"3BR"|"4BR" per homepage filter dropdown), unit_number, owner_name, owner_contact, owner_email, monthly_rent (PHP, int, no decimals), description, images (comma-joined string of paths, not an array), status ("available"|"leased"|"maintenance" per `units.statusAvailable/Leased/ Maintenance` i18n keys), created_at (ISO), tags (comma-joined string, nullable — observed values: `balcony`, `pet`, `split_ac`), building_name, building_city, building_towers, agent_id, agent_name, agent_avatar`. Images are stored as comma-separated string, not a JSON array — a schema smell (inferred: backend is a single flat SQL table joined with buildings, not a normalized media table). **Sitemap/routing mismatch (observed, notable):** `sitemap.xml` lists 13 URLs — the homepage, 7 stale `/units?building_id=N` (N=1–7) query-string pages, and 5 `/units/{id}` permalinks (ids 2,3,5,7,9). But `/units?building_id=1` returns a live **404** (`x-matched-path: /404`, `x-next-error-status: 404`) — the app apparently used to have a server-rendered `/units` list route and has since moved all listing/filter UI to client-side state on `/`, without updating (or 301-redirecting) the sitemap. The `/api/public/buildings` response also only returns 4 buildings even though the sitemap references building_id up to 7 — buildings 3, 6, 7 exist in the DB/sitemap history but are no longer surfaced by the public API (inferred: deleted or deliberately hidden). This is a real, observable SEO/architecture defect worth avoiding in our own build. ## 4. Feature inventory Enumerated from the live rendered homepage, the unit detail page, and the full embedded i18n dictionary (`en` locale, ~500 keys, extracted from `_next/static/chunks/ 768-1e82e92bd9a4f12c.js`): - **Search filters** (all on the homepage, single-select dropdowns, no price-range slider observed): City (Taguig/Makati/Quezon City/Pasay), Condo (building name), Unit Type (Studio/1BR/2BR/3BR/4BR), Tag (With Balcony/Pet Friendly/Split-type Aircon), plus a free-text "Search condo name..." box. No bedroom-count vs unit-type distinction, no bathroom filter, no price filter, no amenities beyond the 3 tags observed. - **Map:** not observed. No map library shipped, no lat/lng fields in the unit JSON shape, no map UI on listing or detail pages. - **Gallery/media:** image carousel on detail page (‹ › arrows observed in rendered DOM), 2 images per unit typical, served from `/uploads/units/*.png` — plain file uploads, not a CDN-transformed media pipeline (images are then re-optimized by Next.js Image on the way out). - **Agent/lead contact mechanism:** **"Contact Agent on Telegram"** button on the detail page (confirmed both in i18n keys `chat.contactAgent`/`chat.telegramPrompt` and directly in the rendered page for unit 9), plus an agent avatar/name block ("Maria Santos"). Not a phone/WhatsApp click-to-call on the public listing page itself (WhatsApp is only mentioned in the About-page narrative as the old pain-point tool agents used before HOMEX, not as the in-product contact channel). Separately, a general "Contact Us" page offers Email, **Telegram**, and Facebook channels plus a name/email/message form (`contact.*` keys). Internally (dashboard-gated) there's also a full agent↔landlord↔tenant **Chat/ Conversations** system (`chat.*` keys — conversations list, send/read state, "Inquiry about {condo} — Unit {unit}" auto-subject). - **Saved search / alerts / email digests:** not observed. No saved-search, favorite, or email-alert strings found anywhere in the i18n dictionary or bundles. - **User accounts/auth:** full custom auth — Login, Register ("I am a..." role picker), Forgot Password (email reset link), Reset Password, Change Password (forced on first login via temp password), all with dedicated i18n strings. Four roles: Admin, Agent, Landlord, Tenant, each with a distinct dashboard. - **Monetization:** not observed. No ads, no "featured"/"boosted"/"premium" listing concept, no subscription/paywall strings anywhere in the bundles. The product's actual monetization is presumably a **B2B SaaS subscription for agents/landlords/property managers** to use the rent/lease/commission-tracking dashboard (inferred from the whole feature set — this is a vertical SaaS, not an ad- supported classifieds site). - **i18n & currency:** English / Simplified Chinese (`zh`) toggle only — no Filipino/ Tagalog. Currency is PHP only, formatted as `₱XX,XXX/mo`, no currency switcher observed. - **Mobile app:** not observed. No app-store badges, deep-link meta tags, or smart-banner markers found. - **Landlord/property-management back-office (dashboard, gated, not directly crawled but fully inventoried via i18n keys):** rent-record generation with a payment **schedule** (per-period rows), tenant-uploaded **proof-of-payment** images with agent/landlord **confirmation** workflow, automatic **overdue detection** with "all parties notified" alerting, lease creation with **multi- tenant** support (comma-separated names/emails/phones), configurable **payment frequency** (monthly/bi-monthly/quarterly/semi-annual/annual/other), lease **document upload** (contract + receipt, PDF/image/ZIP/RAR/7Z up to 20MB), **agent commission** tracking with paid/unpaid status and monthly summaries, a **notifications** center, and an **account-management** screen (admin can disable/reset-password/delete agent/landlord/tenant accounts, auto-generates temp passwords). Landlord and tenant accounts are **auto-created** from the email entered when an admin/agent adds a unit owner or a lease tenant (`units.ownerEmailHint`, `leases.tenantEmailsHint`) — a genuinely clever onboarding trick worth studying even though it's out of scope for our static demo. ## 5. UX & content notes - Homepage layout: sticky header (logo + language toggle + Sign In) → hero band with headline "Available Units for Rent" / "Find your perfect condo in Metro Manila" + centered search box → filter bar (4 dropdowns) directly below the hero → result count ("5 units found") → responsive card grid → footer (About · Contact Us · copyright · Privacy Policy). - Unit cards show: price (large, bold, brand-blue `₱`), building name, tag pills (amber), unit type / area / city, tower + floor chips, and an "Available" status pill (green). - Detail page: back-to-listings link, image carousel, price header with status pill, city, a details grid (unit type/area/tower/floor), free-text description, agent card with initial-avatar + name + "Contact Agent on Telegram" CTA + "Need help?" micro-copy, and a "More units in this condo" related-listings rail. - Brand color is a mid-blue (`theme-color`/`#185FA5`), applied consistently to price text and primary buttons in the rendered screenshots. - Copy is confident/startup-y ("Condo Management for Metro Manila", "Four-Role System", "Synced Reminders") — positions itself to agents/landlords as a management tool first, listing portal second. ## 6. SEO & metadata - `` and all meta/OG/Twitter tags are **static and site-wide** — identical on homepage, listing, and every unit detail page (`HOMEX — Condo Rentals in Metro Manila` / same description / same `og:image: https://www.homex.ph/og-home.png`). No per-listing title, description, or OG image — a missed SEO opportunity (a detail page for a ₱24,000/mo Pasay studio should really title itself around that unit). - `robots.txt`: `Allow: /`, `Disallow: /dashboard/`, `Disallow: /api/`, `Sitemap: https://www.homex.ph/sitemap.xml`. - `sitemap.xml`: only 13 URLs total (see §3 for the stale-route mismatch finding); `changefreq`/`priority` set per URL type (home: daily/1.0, building query pages: weekly/0.5, unit permalinks: weekly/0.8). No hreflang tags anywhere despite having an EN/ZH toggle — the Chinese UI is **not** exposed via a crawlable `?lang=zh` URL or hreflang alternate, so it's invisible to search engines (inferred: language state is pure client-side React state, not URL-driven). - No JSON-LD (`RealEstateListing`, `Product`, `Organization`, `BreadcrumbList`, etc.) anywhere — a meaningful SEO gap relative to how a real property portal should mark up listings for Google's rich-results / real-estate schema. ## 7. Takeaways for property-portal 1. **Per-listing SEO is worth doing properly, unlike HOMEX.** Since property-portal is a static export, we can trivially generate a unique `<title>`/meta description/OG image per listing at build time — HOMEX's identical-meta-everywhere approach is a concrete anti-pattern to avoid. Consider adding `RealEstateListing` JSON-LD per detail page (HOMEX has none) — cheap win for a demo that wants to look more finished than a real competitor. 2. **Keep contact info agent-brokered, never expose raw owner PII in a public API/ payload.** HOMEX's `/api/public/units` leaking `owner_name/owner_contact/ owner_email` unauthenticated is exactly the kind of mistake to call out and avoid; our mock data/contact flow should route through an "agent"/"contact form" abstraction even in the static demo, not raw owner records. 3. **A single clear lead-contact CTA (their "Contact Agent on Telegram") beats a vague "inquire" form.** For our booking/viewing stub, one prominent, channel- specific CTA per listing (we already have a booking stub — keep it singular and obvious, mirroring this pattern) reads more credible than a generic contact form buried lower on the page. 4. **Don't ship filters we can't back with data.** HOMEX's filter set is deliberately small (city, building, unit type, one tag dropdown, free text) and every option is backed by real distinct values in their ~9-unit dataset — no filter offers choices that return zero results. With our ~50 mock listings we have more room, but the lesson holds: match filter granularity (price range, bedrooms, amenities) to what the mock data actually varies across, and sanity-check that no filter combination dead-ends. 5. **Map + saved-search/alerts are real differentiators to keep**, since HOMEX has neither — our Leaflet map and saved-search-alert feature already out-do this specific competitor and should be emphasized in any demo narrative that references it. 6. **Keep the sitemap/routing in sync with actual routes** — HOMEX's sitemap references a now-404'ing `/units?building_id=N` route, a visible, easy-to-avoid bug. Since our site is a static export, regenerate the sitemap from the same data source that generates the static listing pages so this class of drift is structurally impossible. ## Matrix row Category | Framework | Host/CDN | Search filters | Map | Saved search/alerts | Agent/lead contact | Auth | Listing data source | Notable API endpoints | Monetization | i18n/currency | Mobile app | Standout feature --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- Condo rental management SaaS (listing micro-site is a lead-gen front end) | Next.js (App Router, RSC) | Vercel (direct, no CDN in front) | City, Condo/building, Unit Type (Studio–4BR), single Tag dropdown, free-text search | not observed | not observed | "Contact Agent on Telegram" button + agent name/avatar; separate Email/Telegram/Facebook contact page | Custom email+password, 4 roles (Admin/Agent/Landlord/Tenant), forced password change on first login, auto-created landlord/tenant accounts from email | Client-fetched JSON from own `/api/public/*` endpoints (Postgres/MySQL-style flat rows, joined with building) | `GET /api/public/buildings`, `GET /api/public/units?building_id=&city=&tower=&unit_type=&tags=&search=&status=` | not observed (inferred B2B SaaS subscription for agents/landlords, not ads) | EN / Simplified Chinese toggle (client-state only, no hreflang); PHP only, no currency switcher | not observed | Full back-office: rent-payment schedule + proof-of-payment confirmation workflow, agent commission tracking, multi-tenant lease documents, auto-account-creation from email