EMBEDDABLE_LISTINGS_WIDGET - Alphabiz Docs

Embeddable Listings Widget

The AlphaBiz Listings Widget allows partner organizations to embed their business listings on external websites using a simple custom HTML element.

Quick Start

Add these two lines to your HTML page:

<!-- The widget element -->
<alphabiz-listings
  org-id="YOUR_ORGANIZATION_ID"
  api-base="https://app-v2.alphabiz.org/api">
</alphabiz-listings>

<!-- Load the widget script -->
<script src="https://app-v2.alphabiz.org/pl.js"></script>

Replace YOUR_ORGANIZATION_ID with your organization’s UUID.

Embed Methods

The widget supports three embedding methods:

1. Web Component (Default)

Uses Shadow DOM for style-isolated custom element. Best for JavaScript API access and custom event handling.

2. iFrame via JavaScript

Add embed-method="iframe" to use an iframe instead of Shadow DOM:

<alphabiz-listings
  embed-method="iframe"
  org-id="YOUR_ORGANIZATION_ID"
  api-base="https://app-v2.alphabiz.org/api"
  height="600px">
</alphabiz-listings>

<script src="https://app-v2.alphabiz.org/pl.js"></script>

3. Direct iFrame

For maximum simplicity, embed the listings page directly:

<iframe
  src="https://app-v2.alphabiz.org/embed/listings?org=YOUR_ORG_ID&view=grid&theme=light"
  width="100%"
  height="600"
  frameborder="0"
  title="Business Listings">
</iframe>

Method Comparison

Feature Web Component iFrame (via JS) Direct iFrame
Style isolation Shadow DOM Full (iframe) Full (iframe)
JavaScript API ✅ Full Limited None
Custom events None None
CSS variables None None
Simplest setup Medium Easy Easiest
Works without JS No No Yes

Live Demo

A working sample is available at:

docs/samples/embed-listings-sample.html

Open this file in a browser and use the configuration panel to test with your organization ID.

You can also pass the organization ID via URL parameter:

embed-listings-sample.html?org-id=YOUR_ORGANIZATION_ID

Configuration Attributes

The <alphabiz-listings> element accepts the following attributes:

Required

Attribute Type Description
org-id UUID Your organization’s unique identifier

Embed Method

Attribute Type Default Description
embed-method iframe (none) Set to iframe to use iframe embedding instead of web component

API Configuration

Attribute Type Default Description
api-base URL https://app-v2.alphabiz.org/api API endpoint for fetching listings

Display Options

Attribute Type Default Description
view grid | list grid Layout style for listings
theme light | dark light Color theme
columns 1-4 3 Number of grid columns (grid view only)
compact boolean false Use compact card layout
height CSS value auto Container height

Feature Toggles

Attribute Type Default Description
show-filters boolean true Show filter controls
show-search boolean true Show search input
show-map boolean false Show map view
show-price boolean true Display asking prices

Filtering Options

Attribute Type Description
categories string Comma-separated category IDs to filter by
location string Location filter (city, state, or coordinates)
min-price number Minimum asking price filter
max-price number Maximum asking price filter
radius number Search radius in miles (requires location)

Pagination

Attribute Type Default Description
items-per-page number 20 Listings per page
sort string relevance Sort order for results

JavaScript API

The widget exposes methods for programmatic control:

// Get reference to the widget
const widget = document.querySelector('alphabiz-listings');

// Set filters programmatically
widget.setFilters({
  categories: 'category-uuid-1,category-uuid-2',
  minPrice: 100000,
  maxPrice: 500000,
  location: 'New York, NY',
  radius: 25
});

// Change view mode
widget.setView('list');  // or 'grid'

// Refresh listings
widget.refresh();

// Export listings to CSV
widget.export('csv');

Available Methods

Method Parameters Description
setFilters(filters) Object Apply multiple filters at once
setView(view) 'grid' | 'list' Change display layout
refresh() none Reload listings from API
export(format) 'csv' Download listings data

Events

The widget dispatches custom events that you can listen for:

listing:clicked

Fired when a user clicks on a listing card.

document.addEventListener('listing:clicked', function(event) {
  console.log('Listing clicked:', event.detail);
  // event.detail contains:
  // {
  //   id: 'listing-uuid',
  //   title: 'Business Name',
  //   url: 'https://app-v2.alphabiz.org/profile/slug',
  //   listing: { /* full listing object */ }
  // }

  // Navigate to the listing detail page
  window.location.href = event.detail.url;
});

alphabiz:ready

Fired when the widget script is fully loaded and ready.

window.addEventListener('alphabiz:ready', function() {
  console.log('AlphaBiz widget is ready');
  // Safe to interact with widget elements now
});

Styling

The widget uses Shadow DOM for style isolation, preventing your site’s CSS from affecting the widget and vice versa.

CSS Custom Properties

You can customize the widget appearance using CSS custom properties on the host element:

alphabiz-listings {
  --alphabiz-primary-color: #2C5282;
  --alphabiz-text-color: #2D3748;
  --alphabiz-background: #ffffff;
  --alphabiz-border-radius: 8px;
  --alphabiz-card-shadow: 0 2px 4px rgba(0,0,0,0.1);
  --alphabiz-columns: 3;
}

Available CSS Variables

Variable Default Description
--alphabiz-primary-color #2C5282 Primary accent color
--alphabiz-text-color #2D3748 Main text color
--alphabiz-background #ffffff Container background
--alphabiz-border-radius 8px Card border radius
--alphabiz-card-shadow 0 2px 4px rgba(0,0,0,0.1) Card shadow
--alphabiz-columns 3 Grid column count

Responsive Behavior

The widget is responsive by default: - Desktop (> 1024px): Uses configured column count - Tablet (768px - 1024px): 2 columns - Mobile (< 768px): 1 column

Auto-Detection for Partner Domains

If the widget script is loaded from a partner domain (not app-v2.alphabiz.org), it will automatically:

  1. Detect the domain from the script URL
  2. Look up the organization ID from the backend
  3. Set the org-id attribute automatically

This allows partner sites to use the widget without explicitly specifying the organization ID:

<!-- On a partner site, org-id is optional if domain is registered -->
<alphabiz-listings></alphabiz-listings>
<script src="https://partner-domain.com/pl.js"></script>

Complete Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Our Business Listings</title>
  <style>
    /* Customize the widget appearance */
    alphabiz-listings {
      --alphabiz-primary-color: #1a365d;
      --alphabiz-border-radius: 12px;
    }

    .listings-section {
      max-width: 1200px;
      margin: 0 auto;
      padding: 40px 20px;
    }
  </style>
</head>
<body>
  <main class="listings-section">
    <h1>Businesses For Sale</h1>

    <alphabiz-listings
      org-id="your-org-uuid"
      api-base="https://app-v2.alphabiz.org/api"
      view="grid"
      columns="3"
      show-filters="true"
      show-search="true"
      items-per-page="12">
    </alphabiz-listings>
  </main>

  <script src="https://app-v2.alphabiz.org/pl.js"></script>

  <script>
    // Handle listing clicks
    document.addEventListener('listing:clicked', function(event) {
      // Open listing in new tab
      window.open(event.detail.url, '_blank');
    });

    // Log when widget is ready
    window.addEventListener('alphabiz:ready', function() {
      console.log('Widget loaded successfully');
    });
  </script>
</body>
</html>

Backend API Reference

The widget communicates with the following API endpoints:

GET /api/partner-org/{org_id}/listings/public

Returns published listings for the organization.

Query Parameters: - page - Page number (default: 1) - limit - Items per page (default: 20) - category_ids - Filter by category UUIDs - location - Location filter - min_price / max_price - Price range filter - radius - Search radius in miles - sort - Sort order

Response:

{
  "listings": [
    {
      "id": "uuid",
      "title": "Business Name",
      "asking_price": 250000,
      "profile_slug": "business-slug",
      "images": ["url1", "url2"],
      "category": {
        "id": "uuid",
        "name": "Restaurant",
        "image_url": "url"
      },
      "location": {
        "city": "New York",
        "state": "NY"
      }
    }
  ],
  "pagination": {
    "page": 1,
    "pages": 5,
    "total": 100,
    "limit": 20
  },
  "aggregations": {
    "categories": [...],
    "price_ranges": [...]
  }
}

GET /api/partner-site/lookup

Resolves a domain to its organization.

Query Parameters: - domain - The domain to look up

Response:

{
  "organization_id": "uuid",
  "organization_name": "Partner Org Name",
  "theme": {...}
}

Troubleshooting

Widget shows “Organization ID is required”

Ensure you’ve set the org-id attribute with a valid organization UUID.

Listings not loading

  1. Check browser console for errors
  2. Verify the api-base URL is correct
  3. Ensure your organization has published listings
  4. Check CORS configuration if using a custom API endpoint

Styling not applied

CSS custom properties must be set on the alphabiz-listings element itself, not on a parent container. The Shadow DOM prevents external styles from affecting the widget internals.

Events not firing

Ensure you’re listening on the correct element: - listing:clicked - Listen on document (event bubbles) - alphabiz:ready - Listen on window

Browser Support

The widget uses Web Components (Custom Elements v1) and is supported in: - Chrome 67+ - Firefox 63+ - Safari 10.1+ - Edge 79+

For older browsers, include a Web Components polyfill:

<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2/webcomponents-bundle.js"></script>

Security Considerations