You set up a directory widget. You want it to behave a specific way on a specific page: maybe show only one category of listings, require visitors to pick all filters before seeing results, or pre-fill filters from a URL.
This page is the complete reference for the widget's JavaScript configuration. Each option is opt-in, well-defined, and works with the same embed snippet you already have.
You don't need code to use EmbedDirectory
Most customers never touch this page. The dashboard handles everything: layout, filters, branding, custom fields, integrations. If your goal is to add a directory to your site, see the quick start guide.
The JavaScript API is for customers who want custom behavior the dashboard doesn't expose. If something here looks tricky, email hello@embeddirectory.com and we'll write the snippet for you.
Quick Start
The basic embed snippet is two pieces: a container element and a script that initializes the widget into it.
<div id="embed-directory-widget"></div>
<script>
(function() {
var script = document.createElement("script");
script.src = "https://embed.embeddirectory.com/widget.js";
script.async = true;
script.onload = function() {
window.EmbedDirectoryWidget.init({
elementId: "embed-directory-widget",
widgetId: "widget_xxxxxxxxxxxxxxxx"
});
};
document.head.appendChild(script);
})();
</script>
Replace widget_xxxxxxxxxxxxxxxx with the widget ID from your Embed page. That's a complete, working embed.
To customize behavior, add a config object alongside elementId and widgetId. Every option below goes inside config.
Configuration Reference
| Option | Type | Description |
|---|---|---|
preFilter | object | Restrict listings before any user filtering. Declarative rules with and / or logic. |
customFilterFunction | function | Run your own filter logic on each render. Most powerful option. |
initialFilter | object | Pre-select filter values when the widget loads. |
urlParams | boolean | Read filter values from the page URL. Default: true. |
locale | string | Force a specific display language (e.g. "en", "es"). |
A Note on Field and Filter Labels
Examples below reference fields and filters by their dashboard label (e.g. "Make", "Year"). This reads naturally and matches what you see in your dashboard.
Labels are matched case-insensitively. If multiple fields share a label, the widget uses the first match and logs a console warning. If you rename a field later, update your snippet.
For rename-safe references, use the field's numeric ID instead. The field_id is shown in your widget settings or in the REST API field list. Both forms work everywhere a field or filter is referenced.
Pre-Filter Rules
Restrict the underlying listing set before any visitor interaction. Useful when you want one widget to show a specific slice of your directory: only one category, only listings in a region, or anything you can express as a rule.
config: {
preFilter: {
mode: "and",
rules: [
{ field: "Category", operator: "contains", value: "Hotel" }
]
}
}
Modes
| Mode | Behavior |
|---|---|
and | All rules must match. Default. |
or | At least one rule must match. |
Operators
| Operator | Value | Behavior |
|---|---|---|
contains | string | For tag and category fields, value is one of the field's values. For text fields, exact match. |
contains_any | array | Match if any of the values is present. More efficient than multiple or rules on the same field. |
contains_all | array | Match only if every value is present. |
not_contains | string | Inverse of contains. |
equals | string | Exact match. Same as contains for text fields. |
not_equals | string | Inverse of equals. |
Combine Rules
preFilter: {
mode: "and",
rules: [
{ field: "Category", operator: "contains", value: "Restaurant" },
{ field: "City", operator: "contains_any", value: ["Austin", "Denver"] }
]
}
This shows restaurants located in Austin or Denver. The outer mode is and (both rules must match); contains_any handles the Austin-or-Denver part inside the second rule.
Custom Filter Function
A function you define that runs after the built-in filter pipeline on every render. Use this when declarative preFilter rules aren't enough: dynamic logic, conditional empty states, or filtering tied to your own data.
The function receives a context object and returns either an array of items or an object with items and an optional emptyMessage.
Context Object
| Property | Type | Description |
|---|---|---|
items | array | The listings already filtered by built-in filters. |
activeFilters | object | Current filter values keyed by filter ID. |
searchFilters | array | The widget's configured filters (id, type, label, config). |
fields | array | The widget's field definitions. |
settings | object | The widget's full settings. |
geoSearchLocation | object or null | Active location-search coordinates, if any. |
Example: Require All Filters Before Showing Results
A common pattern: hold back results until the visitor has selected every filter, then show the matching listing.
config: {
customFilterFunction: function(context) {
var hasValue = function(value) {
if (value === null || value === undefined) return false;
if (typeof value === "string") return value.trim().length > 0;
if (Array.isArray(value)) return value.length > 0;
if (typeof value === "object") return Object.keys(value).length > 0;
return true;
};
var allFiltersSet = context.searchFilters.every(function(filter) {
return hasValue(context.activeFilters[filter.id]);
});
if (!allFiltersSet) {
return {
items: [],
emptyMessage: "Please select all " + context.searchFilters.length + " filters to see your match."
};
}
return context.items.slice(0, 1);
}
}
This pattern reads the widget's actual filter list at runtime, so it keeps working if you add, remove, or rename filters in the dashboard.
Return Values
| Return | Effect |
|---|---|
| Array of items | Replace the result list. Default empty-state message is used. |
{ items, emptyMessage } | Replace the result list and customize the empty-state message. |
Initial Filter Values
Pre-select filter values when the widget loads. Useful for landing pages dedicated to a specific category, location, or audience.
config: {
initialFilter: {
"Category": "Restaurant",
"City": "Austin"
}
}
URL parameters take priority over initialFilter values. If a visitor lands on a URL with filter parameters, those win.
URL Parameters
The widget reads filter values from the page URL automatically. This is on by default. Set urlParams: false to opt out.
?q=coffee
?filter_City=Austin
?filter_Make=Honda
| Parameter | Effect |
|---|---|
q or search |
Fills the first search filter. |
filter_<Label> |
Fills the filter whose linked field matches <Label>. |
<type> (e.g. dropdown) |
If only one filter of that type exists, fills it. |
For range filters, use _min and _max suffixes:
?filter_Price_min=10&filter_Price_max=100
To disable URL parameter handling entirely:
config: { urlParams: false }
Locale
Force a specific display language. Defaults to your widget's configured default. Useful for serving the same widget in different languages on different pages.
config: { locale: "es" }
You manage available languages and translated phrases on the Phrases page.
Debugging
Open your browser's developer console while the widget loads. The widget logs each step of its filter pipeline (Applying pre-filter, Applying custom filter function, After ... filter:) so you can see how listings move through your configuration.
If you reference a field or filter by label that doesn't match (typo, rename, ambiguous name), the widget logs a single warning per unique reference:
[EmbedDirectory] Field "Make" not found. If you renamed it, update
your snippet, or use the field's numeric ID.
Common gotchas:
-
customFilterFunctionreturns nothing. The function must return either an array or an object withitems. Returningundefinedreverts to the built-in filtered list. -
Filter values look "set" but aren't. Range filters use
[min, max]arrays; toggle filters use booleans; multi-select filters use arrays. Checkcontext.activeFiltersin the console to see actual shapes. -
Pre-filter rule has no effect. The console warning will tell you if the field reference didn't resolve. If there's no warning, double-check the operator matches your data type (e.g.
contains_anyexpects an arrayvalue).
Need Help?
If you're not sure how to express what you want, send the goal in plain language to hello@embeddirectory.com. We'll write the snippet for you.
For programmatic listing management (creating, updating, syncing listings from your own systems), see the REST API documentation.