React SDK
Install @echopm/react — hosted production listing UI by default, plus search cards and client mode.
@echopm/react (v0.4+ on npm) embeds EchoPM listings on partner sites.
By default, UnitList and PropertyPage* load production EchoPM UI in an iframe (same OpenUnits, gallery, and header as the live property page). Apply and Schedule Tour use EchoPM sign-in dialogs on our domain.
Product overview: Bring your own website · keys & iframe: Website embed
Prerequisites#
- A publishable embed key from Manager → Property → Settings → Listing → Website embed
- Property is searchable with available units
- React 18+ (or 19)
Install#
npm install @echopm/react
# or
pnpm add @echopm/react
Import styles when using mode="client" or building-block components (PropertyCard, SearchWidget, etc.):
import "@echopm/react/styles.css";
Set env on the marketing site:
NEXT_PUBLIC_ECHOPM_EMBED_KEY=your_embed_key_here
Quick start (hosted iframe)#
"use client";
import { EchoPMProvider, UnitList } from "@echopm/react";
export function PropertyUnits({ propertyId }: { propertyId: string }) {
return (
<EchoPMProvider
publishableKey={process.env.NEXT_PUBLIC_ECHOPM_EMBED_KEY!}
onEvent={(event) => {
console.log(event.name, event);
}}
>
<UnitList propertyId={propertyId} showApply showScheduleTour />
</EchoPMProvider>
);
}
The SDK iframes https://www.echopm.app/embed/units (auto-height via postMessage). You get production OpenUnits, not a parallel redesign.
Optional theme primary:
<EchoPMProvider
publishableKey={process.env.NEXT_PUBLIC_ECHOPM_EMBED_KEY!}
theme={{ primary: "#3D7C62" }}
>
<UnitList propertyId={propertyId} showApply />
</EchoPMProvider>
Property pages#
import {
PropertyPageSimple,
PropertyPageFull,
PropertyPage,
} from "@echopm/react";
<PropertyPageSimple propertyId={propertyId} showApply />
<PropertyPageFull propertyId={propertyId} showApply />
{/* Alias of PropertyPageSimple */}
<PropertyPage propertyId={propertyId} showApply />
<PropertyPageFull
propertyId={propertyId}
exclude={["neighborhood", "similar", "poweredBy"]}
/>
Hosted routes: /embed/property (simple) and /embed/property-full.
Search cards & list#
Search-style media cards (image, price pill, beds/baths/sqft) — same visual language as EchoPM /search:
import { PropertyCard, PropertyList, SearchWidget } from "@echopm/react";
<SearchWidget /> {/* org-scoped search → PropertyList grid */}
<PropertyList properties={hits} layout="grid" />
<PropertyCard property={hit} />
layout on PropertyList: "grid" (default) or "list".
Custom layout (mode="client")#
Use the embed API + portable listing UI when you need headless data or custom markup:
<UnitList propertyId={propertyId} mode="client" showApply>
{({ payload }) => (
<ul>
{payload.availableUnits.map((unit) => (
<li key={unit.id}>
Unit {unit.unitNumber} — {unit.rent != null ? `$${unit.rent}` : "Call"}
</li>
))}
</ul>
)}
</UnitList>
Passing children, header, or renderApply selects client automatically unless you set mode explicitly.
On EchoPM-hosted pages you can pass renderApply / renderScheduleTour for in-page sign-in and apply/tour dialogs. On partner origins, default CTAs open EchoPM (apply/schedule) in a new tab.
Component map#
| Export | Default behavior |
|---|---|
EchoPMProvider | Key, API origin, theme, onEvent |
UnitList | Hosted iframe → production OpenUnits |
PropertyPageSimple / PropertyPageFull | Hosted iframe → production listing |
PropertyCard / PropertyList | Search-result cards (client UI; import styles) |
SearchWidget | Org search API + PropertyList |
LeadForm / ApplyButton / ScheduleTourButton | Building-block CTAs |
PoweredBy | Attribution |
EmbedFrame / buildHostedEmbedUrl | Low-level iframe helpers |
API base URL#
Defaults to https://www.echopm.app. Partners do not need to pass apiBaseUrl.
| When to override | apiBaseUrl |
|---|---|
| Local EchoPM unified | http://localhost:3000 |
| Staging tenant app | your staging origin |
Hosted iframes and /api/embed/v1/* both use this origin. Requests use header X-EchoPM-Embed-Key.
Analytics#
onEventonEchoPMProviderfor partner-site analytics- Iframes also
postMessageevents of typeechopm-embed-eventandechopm-embed-resize
Playground#
With a key: https://www.echopm.app/embed/demo?propertyId=…&key=…
Related#
- Website embed overview — iframe + keys
- Bring your own website — product page
- Beta scope — REST/MCP vs embed status
