Inspect Langere Commercial Property Filters and Cards

Site langere.comTask inspect-commercial-property-filters-and-cardsVersion v1Updated Jul 28, 2026Category real-estate

Identify commercial-property filter controls, apply a property-type filter such as Retail, and extract the resulting property card structure and links on Langere. This skill was captured from a live agent session on langere.com and publishes here verbatim, exactly as an agent receives it.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Purpose

Inspect Langere's commercial-property listing filter mechanism and extract structured HTML details from property cards, including the filtered Retail view.

When to Use

Use when a caller needs to discover available commercial-property type filters, apply one of them, or inspect/extract the listing cards shown on Langere's commercial-properties page.

Workflow

  1. Navigate directly to https://langere.com/commercial-properties and wait for the page's listing JavaScript to finish rendering (about 4 seconds).
  2. Run the following evaluator on the loaded page. It records the type-filter controls, applies the Retail filter through Langere's client-side control, waits briefly for the DOM visibility changes, and returns the visible Retail cards plus their HTML and links:
(async () => {
  const text = (el) => (el?.textContent || "").replace(/\\s+/g, " ").trim();
  const attrs = (el) =>
    Object.fromEntries(
      Array.from(el?.attributes || []).map((a) => [a.name, a.value]),
    );
  const filter = document.querySelector('ul[data-filter="type"]');
  const options = Array.from(filter?.querySelectorAll("li a") || []).map((a) => ({
    label: text(a),
    href: a.href,
    attributes: attrs(a),
    liClass: a.parentElement?.className || "",
  }));
  const retail = options.find((o) => o.label.toLowerCase() === "retail");
  if (retail) {
    const retailAnchor = Array.from(filter.querySelectorAll("li a")).find(
      (a) => text(a).toLowerCase() === "retail",
    );
    retailAnchor?.click();
    await new Promise((resolve) => setTimeout(resolve, 1200));
  }
  const visible = (el) => {
    let node = el;
    while (node && node !== document.documentElement) {
      const style = getComputedStyle(node);
      if (
        style.display === "none" ||
        style.visibility === "hidden" ||
        style.opacity === "0"
      )
        return false;
      if (node.classList?.contains("hidden")) return false;
      node = node.parentElement;
    }
    return true;
  };
  const cards = Array.from(document.querySelectorAll(".section-property"));
  const retailCards = cards.filter(visible).map((card) => ({
    html: card.outerHTML,
    text: text(card),
    attributes: attrs(card),
    propertyLinks: Array.from(
      card.querySelectorAll('a[href*="/commercial-property/"]'),
    ).map((a) => ({
      href: a.href,
      text: text(a),
      attributes: attrs(a),
    })),
  }));
  return {
    filterSelector: 'ul[data-filter="type"]',
    filterMode:
      "client-side DOM filtering; the filter control does not expose a navigable URL in the observed page",
    options,
    requestedFilter: "Retail",
    retailFilterFound: !!retail,
    totalCards: cards.length,
    visibleRetailCards: retailCards.length,
    cards: retailCards,
  };
})();

Site-Specific Gotchas

  • The type controls are under ul[data-filter="type"]; locate the option by normalized anchor text rather than assuming an option index.
  • Retail is applied by clicking the matching anchor and changing card visibility in the DOM. No filter URL or query parameter was exposed during inspection, so do not invent a direct Retail URL.
  • Property cards use the .section-property class, while property detail links contain /commercial-property/. Extract card containers rather than treating every matching anchor as a separate card.
  • Wait for the page JavaScript before querying cards or filters; an immediate query can run before the listing markup is available.
  • The evaluator returns raw outerHTML; treat class names and nested markup as site-specific and preserve the card-level link extraction for stable structured results.

Expected Output

An object containing the available commercial-property type options, whether the Retail filter was found, the total number of .section-property cards, the number visible after applying Retail, and each visible card's normalized text, attributes, raw HTML, and commercial-property detail links.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=langere.com&task=inspect-commercial-property-filters-and-cards