Rechat SDK
    Preparing search index...

    Custom Markup (Templates)

    Every listings component renders a built-in layout by default. To use your own HTML instead, put a <template> with {{ ... }} placeholders inside the component — the SDK fills it with live listing data and keeps it in sync.

    If you don't add a template, the built-in layout is used, so this is fully opt-in.

    <rechat-map-listings-grid>
    <template rechat-each="listings">
    <a class="card" href="/listings/{{ id }}">
    <img src="{{ cover_image_url }}" alt="">
    <div class="price" data-format="currency">{{ price }}</div>
    <div>{{ formatted.street_address.text }}</div>
    <span data-format="pluralize:bed">{{ property.bedroom_count }}</span>
    </a>
    </template>

    <template rechat-state="empty"><p>No listings match your search.</p></template>
    </rechat-map-listings-grid>

    rechat-each="listings" repeats its content once per listing. rechat-state="empty" (or "loading") shows content only in that state.

    Write {{ path }} in text or attributes. Paths are dotted property names only — no logic, function calls, or expressions. A missing value renders as empty.

    <h2>{{ formatted.price.text }}</h2>
    <img src="{{ cover_image_url }}">
    <a href="/p/{{ id }}">Details</a>

    Commonly used fields on a listing:

    Path Example
    id, status , Active
    price 1250000
    cover_image_url image URL
    formatted.price.text $1,250,000
    formatted.street_address.text 123 Main St
    formatted.bedroom_count.value 3
    formatted.total_bathroom_count.value 2.5
    formatted.square_feet.text_no_label 2,500
    property.address.city Dallas

    formatted.* fields are ready-to-display strings; use them for prices, counts, and addresses.

    Add data-format="name" to an element that wraps a single {{ }} value:

    Formatter Example
    currency 1250000$1,250,000
    number 25002,500
    date Mar 5, 2024
    pluralize:bed / pluralize:bath 3 beds / 1 bath
    uppercase / lowercase case change
    <span data-format="currency">{{ price }}</span>
    

    data-if="path" removes an element when the value is empty/false:

    <span class="badge" data-if="status">{{ status }}</span>
    
    Component Directive Renders
    <rechat-map-listings-grid> rechat-each="listings" your card, per listing
    <rechat-listing-details> rechat-details (single listing) your details-modal body
    <rechat-property-search-form> rechat-form your search form
    <rechat-filter-*> inner <template> your filter dropdown (see below)

    In <rechat-listing-details> the single listing is under listing, e.g. {{ listing.formatted.price.text }}.

    <rechat-filter-*> accept a <template> whose controls bind back to the search with rechat-model:

    <rechat-filter-price>
    <template>
    <button rechat-toggle>{{ label }}</button>
    <div data-if="isOpen">
    <select rechat-model="minimumPrice"></select>
    <select rechat-model="maximumPrice"></select>
    <button rechat-reset>Clear</button>
    </div>
    </template>
    </rechat-filter-price>
    • rechat-model="key" two-way binds an <input>/<select> to a filter value.
    • rechat-toggle / rechat-open / rechat-close control the dropdown; rechat-reset clears the filter.
    • The template scope exposes isOpen, label, badge, hasValue (beds/baths also min).
    • Templates are safe by design: <script>, inline event handlers (onclick), and style="{{…}}" are not allowed, and javascript:/data: URLs are blocked.
    • Cards are reused by listing id as results change, so the DOM isn't rebuilt on every update.