BMLT Meeting List
An embeddable NA meeting finder widget for any website.
Live DemoOverview
BMLT Meeting List is a self-contained JavaScript widget that queries a BMLT root server and renders a fully featured meeting finder — search, filters, list view, and an interactive map.
It ships as a single JavaScript file with all CSS injected at runtime. No stylesheets, no build steps, no framework required on the host page.
Quick Start
Add a container div with your BMLT root server URL, then load the script:
<div
id="bmlt-meeting-list"
data-root-server="https://your-server/main_server"
></div>
<script src="https://cdn.aws.bmlt.app/bmlt-client/app.js"></script>
The widget initializes automatically when the script loads. No JavaScript required on your end.
Data Attributes
All configuration is set as data-* attributes on the #bmlt-meeting-list div.
| Attribute | Description | |
|---|---|---|
| data-root-server | Required |
Full URL to your BMLT root server.
Example: https://example.org/main_server
|
| data-service-body | Optional |
Filter meetings to one or more service bodies. Accepts a single numeric ID or a
comma-separated list. Child service bodies are always included (recursive).
Omit to show all meetings on the server.
Single: "42"
Multiple: "42,57,103"
|
| data-view | Optional |
Default view when the widget loads.
Values: list (default) or map
Can be overridden at runtime by the ?view= query parameter (see URL Query Parameters).
|
Global Config Object
For options not available as data attributes, define BmltMeetingListConfig
as a global variable before loading the script.
<script>
var BmltMeetingListConfig = {
defaultView: 'map'
};
</script>
<script src="app.js"></script>
| Property | Type | Description |
|---|---|---|
| defaultView | 'list' | 'map' |
Override the default view. Takes precedence over data-view. |
| language | string |
Override the UI language (e.g. 'es', 'fr').
Defaults to navigator.language, falling back to English.
Supported: en, es, fr, de, pt, it, sv, da.
|
| calendar | boolean |
Show the Add to Calendar button on meeting detail (iCal & Google Calendar).
Default: true. Set to false to hide it.
|
| columns | string[] |
Columns to show in list view. Default: ['time', 'name', 'location', 'address'].
Omit any column name to hide it. Available values: time, name, location (venue/building name),
address (street address with in-person/online badges), service_body.
service_body is hidden by default — add it explicitly to show the service body name.
|
| geolocation | boolean |
Show a Near Me button and auto-geolocate on page load to find meetings near the user.
Requires HTTPS. Default: false. Falls back to full meeting load if permission is denied.
|
| geolocationRadius | number |
Search radius in miles when using geolocation. Default: 10.
|
| map.tiles | TilesConfig |
Custom map tile provider. Replaces the default OpenStreetMap tiles. See Tile Provider below. |
| map.tiles_dark | TilesConfig |
Alternate tile provider used when prefers-color-scheme: dark.
Swaps automatically on OS theme change.
See Dark Mode Tiles below.
|
| map.markers.location | MarkerConfig |
Custom map marker for meeting locations. Replaces the default NA marker. See Marker Config below. |
Language
The widget automatically detects the visitor's language from navigator.language and falls back to English.
Override it with the language config property:
<script>
var BmltMeetingListConfig = {
language: 'es'
};
</script>
<script src="app.js"></script>
Language codes are matched on the base tag, so 'fr-CA' uses fr.
Supported languages:
| Code | Language |
|---|---|
en | English |
es | Spanish |
fr | French |
de | German |
pt | Portuguese |
it | Italian |
sv | Swedish |
da | Danish |
Geolocation
Enable the Near Me button with geolocation: true. When enabled, the widget
also attempts to geolocate the user automatically on page load and show meetings nearby.
Requires a secure context (HTTPS). If permission is denied or unavailable, the widget silently
falls back to loading all meetings.
<script>
var BmltMeetingListConfig = {
geolocation: true,
geolocationRadius: 25 // miles, default 10
};
</script>
<script src="app.js"></script>
URL Query Parameters
The ?view= query parameter sets the initial view and overrides data-view
and defaultView:
| Value | Behaviour |
|---|---|
list | Force list view on load |
map | Force map view on load |
auto |
Geolocate on load — success shows map with nearby results; failure falls back to list with all meetings |
Example: https://example.org/meetings/?view=auto
?view=list and ?view=map disable auto-geolocation even if geolocation: true is set.
CSS Variables
The widget exposes CSS custom properties so you can theme it without touching JavaScript.
Set any of these on the #bmlt-meeting-list element — only specify the ones you want to override.
| Variable | Default | Controls |
|---|---|---|
| --bmlt-font-family | system-ui, -apple-system, sans-serif | Widget font stack |
| --bmlt-font-size | 16px | Base font size |
| --bmlt-background | #ffffff | Widget and controls bar background |
| --bmlt-text | #111827 | Primary text color |
| --bmlt-border | #e5e7eb | Borders and dividers |
| --bmlt-accent | #2563eb | Active buttons, links, focus indicators |
| --bmlt-accent-light | #eff6ff | Row hover, active filter panel background |
| --bmlt-border-radius | 8px | Card and button corner radius |
| --bmlt-row-alt | #f9fafb | Alternating (even) row background |
| --bmlt-in-person | #15803d | In-person badge text |
| --bmlt-in-person-bg | #dcfce7 | In-person badge background |
| --bmlt-virtual | #1d4ed8 | Virtual badge text |
| --bmlt-virtual-bg | #dbeafe | Virtual badge background |
#bmlt-meeting-list {
--bmlt-accent: #dc2626;
--bmlt-accent-light: #fef2f2;
--bmlt-border-radius: 0px;
}
Dark Mode CSS
Use a CSS media query to adapt the widget's colors when the visitor's OS is in dark mode. This works independently of — or alongside — the dark mode tile option.
@media (prefers-color-scheme: dark) {
#bmlt-meeting-list {
--bmlt-background: #111827;
--bmlt-text: #f9fafb;
--bmlt-border: #374151;
--bmlt-accent: #60a5fa;
--bmlt-accent-light: #1e3a5f;
--bmlt-in-person: #86efac;
--bmlt-in-person-bg: #14532d;
--bmlt-virtual: #93c5fd;
--bmlt-virtual-bg: #1e3a5f;
}
}
CSS Helper Classes
These classes are applied internally and can also be targeted in your own CSS for further customization.
| Class | Used on |
|---|---|
| bmlt-btn-primary | Filled accent buttons — active filter chips, view toggle, Join Meeting |
| bmlt-btn-secondary | Outlined buttons — Get Directions |
| bmlt-link | Link-style buttons — Back, email contact |
| bmlt-badge-in-person | In-person venue badge |
| bmlt-badge-virtual | Virtual venue badge |
| bmlt-card | Detail section cards |
| bmlt-row | Meeting list table rows |
#bmlt-meeting-list .bmlt-btn-secondary:hover {
background-color: transparent;
opacity: 0.8;
}
Tile Provider
By default the map uses OpenStreetMap tiles.
Switch to any Leaflet-compatible tile provider
by setting map.tiles.
| Property | Type | Description |
|---|---|---|
| url | string |
Tile URL template. Use {z}, {x}, {y} placeholders (and {r} for retina where supported). |
| attribution | string |
Attribution HTML displayed in the map's attribution control. Required by most tile providers' terms of service. |
<script>
var BmltMeetingListConfig = {
map: {
tiles: {
url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png',
attribution: '© <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> © <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}
}
};
</script>
<script src="app.js"></script>
Dark Mode Tiles
Set map.tiles_dark to use a different tile layer for visitors with
prefers-color-scheme: dark. The layer swaps automatically when the OS
theme changes — no page reload needed. If omitted, the same tiles are used in all
color schemes.
<script>
var BmltMeetingListConfig = {
map: {
tiles: {
url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png',
attribution: '© <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> © <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
},
tiles_dark: {
url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png',
attribution: '© <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> © <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
},
}
};
</script>
<script src="app.js"></script>
<script>
var BmltMeetingListConfig = {
map: {
tiles: {
url: 'https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/{z}/{x}/{y}?access_token=<pk.your.access.token>',
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
},
tiles_dark: {
url: 'https://api.mapbox.com/styles/v1/mapbox/dark-v10/tiles/{z}/{x}/{y}?access_token=<pk.your.access.token>',
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
},
}
};
</script>
<script src="app.js"></script>
Marker Config
The map.markers.location object lets you replace the default NA map pin
with any image or inline SVG.
| Property | Type | Description |
|---|---|---|
| html | string |
HTML rendered inside the marker element. Typically an <img> tag or inline SVG. |
| width | number |
Icon width in pixels. |
| height | number |
Icon height in pixels. The anchor point is set to the bottom-center of the icon. |
<script>
var BmltMeetingListConfig = {
map: {
markers: {
location: {
html: '<img src="https://example.com/my-marker.png">',
width: 23,
height: 33
}
}
}
};
</script>
<script src="app.js"></script>
Example: Basic Embed
Show all meetings on a public BMLT server:
<div
id="bmlt-meeting-list"
data-root-server="https://latest.aws.bmlt.app/main_server"
></div>
<script src="https://cdn.aws.bmlt.app/bmlt-client/app.js"></script>
Example: Filter by Service Body
Show only meetings belonging to service body 42 (and its children):
<div
id="bmlt-meeting-list"
data-root-server="https://bmlt.sezf.org/main_server"
data-service-body="42"
></div>
<script src="app.js"></script>
Example: Multiple Service Bodies
Pass a comma-separated list to include meetings from several service bodies:
<div
id="bmlt-meeting-list"
data-root-server="https://bmlt.sezf.org/main_server"
data-service-body="42,57,103"
></div>
<script src="app.js"></script>
Example: Default to Map View
<div
id="bmlt-meeting-list"
data-root-server="https://bmlt.sezf.org/main_server"
data-service-body="42"
data-view="map"
></div>
<script src="app.js"></script>
Example: WordPress
Add the following to your theme's functions.php to enqueue the script
and render the widget via a shortcode:
function bmlt_meeting_list_shortcode( $atts ) {
$atts = shortcode_atts( [
'root_server' => '',
'service_body' => '',
'view' => 'list',
], $atts );
wp_enqueue_script(
'bmlt-meeting-list',
'https://cdn.aws.bmlt.app/bmlt-client/app.js',
[],
null,
true
);
$service_body = esc_attr( $atts['service_body'] );
$root_server = esc_url( $atts['root_server'] );
$view = esc_attr( $atts['view'] );
return sprintf(
'<div id="bmlt-meeting-list" data-root-server="%s" data-service-body="%s" data-view="%s" style="height:80vh"></div>',
$root_server,
$service_body,
$view
);
}
add_shortcode( 'bmlt_meeting_list', 'bmlt_meeting_list_shortcode' );
Then use the shortcode in any page or post:
[bmlt_meeting_list root_server="https://bmlt.sezf.org/main_server" service_body="42"]
height: 80vh works well for most page layouts.
Features
- List view — meeting table sorted by day and time, with venue type badges
- Map view — interactive Leaflet map for in-person meetings (including those with an online component); click a marker to see meetings at that location
- Detail view — full meeting info: schedule, address with Google Maps directions, virtual meeting join button, formats, and notes
- Text search — real-time filter across meeting name, location, and notes
- Weekday filter — toggle individual days of the week
- Venue type filter — in-person or virtual (meetings with both an in-person location and an online link appear under both)
- Time of day filter — morning, afternoon, evening, or night
- Recursive service body support — child service bodies are always included
- Multiple service bodies — comma-separate IDs to combine regions
Browser Support
All modern browsers. Internet Explorer is not supported.
- Chrome / Edge 90+
- Firefox 90+
- Safari 14+