Widgets

Website widgets show your live listings on any website you already have, in your brand and language, with no code of your own: paste a snippet and visitors can browse, search, open a listing and send you an Inquiry, which lands in your CRM as a Lead "via widget".

The snippet

A Tenant Admin builds one in the Admin Console under Integrations → Website widgets: pick a widget and its filters, check the live preview, add your website's origin and copy the snippet. It looks like this:

<script type="module" src="https://www.letsrealty.io/widgets/v1/lr.js" data-key="lr_pk_1a2b3c4d_xxxx"></script>
<lr-listings layout="grid" listing="sale" limit="6"></lr-listings>
  • Load the script once per page; every widget on the page shares its data-key. A widget's own key attribute overrides it.
  • The key is a publishable key: it works only on the origins it allows, so add each website (https://www.youragency.com) before you publish the page.
  • The v1 script only ever changes in ways that keep your snippet working, and updates reach every page within minutes.

The widgets

<lr-listings>

Your listings as a grid or a carousel.

| Attribute | Meaning | | --- | --- | | layout | grid (the default) or carousel | | listing | sale or rent (a sale listing also offered for rent matches rent) | | area | an Area's location slug, such as guanacaste | | place | a Place's location slug, such as tamarindo; it wins over area | | type | a property type, such as Condo | | featured | only your featured listings, in their featured order | | min-price, max-price | a price range, in whole numbers | | beds | at least this many bedrooms (1 to 10) | | limit | how many listings (default 6, at most 100) |

The location slugs are the ones in your website's search links (?location=). A value that isn't valid is ignored rather than breaking the widget.

<lr-search>

Search controls (offer, location, property type, price, bedrooms and amenities) built from your own live listings, with the results and paging. It takes the same filter attributes as <lr-listings> to preset the controls, plus amenities (comma-separated amenity keys) and limit (default 12).

<lr-lead-form>

An Inquiry form. Without attributes it is a general inquiry; property="<listing id>" asks about one listing and agent="<Agent id>" writes to one Agent. It passes Cloudflare Turnstile before it sends; a challenge shows only when Turnstile needs one.

<lr-listing-detail>

One listing on a page of your own website, for when you set detail-url (below). It reads the listing's slug from the page's address and shows its gallery, facts, Agent and a lead form. slug="…" names a listing outright.

Opening a listing

Clicking a card opens the listing in a modal: its photos, facts, description, Agent and a lead form, plus View full listing, which opens its page on your letsrealty website. The modal closes with Esc, the close button or the browser's back button, and keeps keyboard focus inside it while open.

To show listings on your own website's pages instead, give the cards a detail-url template with {slug} where the slug goes:

<lr-listings detail-url="/propiedades/{slug}"></lr-listings>

Cards then link to /propiedades/casa-azul, and on that page:

<lr-listing-detail detail-url="/propiedades/{slug}"></lr-listing-detail>

A query works too: detail-url="/listing?id={slug}". Opening a listing, in the modal or on a detail page, counts as a view in your listing stats.

Styling

Widgets render inside a Shadow DOM, so your page's CSS can't break them, and they take your published Theme's colours, fonts and corner style. Override any of them with CSS custom properties on the element:

lr-listings {
  --lr-primary: #0f766e;
  --lr-primary-foreground: #ffffff;
  --lr-font-body: "Inter", sans-serif;
  --lr-radius: 4px;
}

| Property | Used for | | --- | --- | | --lr-background, --lr-foreground | the modal and form fields, and text | | --lr-surface, --lr-border, --lr-border-strong | cards and their borders, field borders | | --lr-muted, --lr-muted-foreground | placeholders and secondary text | | --lr-primary, --lr-primary-foreground | buttons and tags | | --lr-link, --lr-ring | links and the focus ring | | --lr-overlay-scrim | the backdrop behind the modal | | --lr-font-heading, --lr-font-body | headings and text | | --lr-radius, --lr-radius-button | the corners of cards and fields, and of buttons |

For more, style the parts with ::part(): card, button, input, form and modal.

lr-listings::part(card) { box-shadow: none; }
lr-lead-form::part(button) { text-transform: uppercase; }

The "Powered by letsrealty" line can be hidden on the Agency and Enterprise plans, from Integrations → Website widgets.

Languages

A widget speaks its lang attribute, else your page's <html lang>, as long as it is one of your Site Languages, else your Default Language. Listings come in that language where they have a translation; the widget's own text is in English or Spanish.

<lr-listings lang="es"></lr-listings>

SEO

Widgets render in the visitor's browser, so search engines index your listings from your letsrealty website, not from the page that embeds the widget. Your letsrealty website's listing page stays the canonical one; link to it (the modal's View full listing does) rather than copying listing text into your pages.