Script tag reference
The script configures itself entirely from attributes on its own <script> tag.
It identifies that tag once, and every part of the script uses the same
answer. When the app installs the script for you, the browser tells it exactly
which tag it is. Otherwise it takes the first script[data-app-id] on the
page — and if there is more than one, it says so:
[wf-algolia] Found 2 script tags with data-app-id on this page. Using the
first one; the rest are ignored. Remove the duplicates — running two loaders
doubles your Algolia queries and Insights events.
Previously each part of the script searched for the tag separately, so on a
page with two of them your credentials could come from one tag and
data-index from the other.
<script
async
type="module"
src="https://cdn.jsdelivr.net/npm/@candid-leap/wf-algolia@1.0.8/dist/index.js"
integrity="sha384-…"
crossorigin="anonymous"
data-app-id="YOUR_ALGOLIA_APP_ID"
data-search-key="YOUR_SEARCH_ONLY_KEY"
></script>
The app writes this tag for you, pinned to an exact version and carrying the integrity hash for that version. It is shown here so you can recognise it in your page source, not so you can assemble one by hand.
Required
| Attribute | What it does |
|---|---|
| Your Algolia Application ID. Also how the script locates its own tag. Letters and digits only, up to 64 characters. | |
| Search-Only API key. Never the Admin key — the tag is public. |
Missing either one throws during startup. The error is caught and logged as
[wf-algolia] Initialization failed: followed by the message.
The Application ID is checked before anything uses it, because it becomes part of the Algolia hostname the script queries — a malformed one could point requests somewhere you did not intend. Anything outside letters and digits stops startup with the offending value named:
[wf-algolia] Invalid App ID "evil.com". data-app-id must be 1-64 letters and
digits only — copy it from Algolia under Settings, then API Keys.
Index
| Attribute | Default | What it does |
|---|---|---|
| none | Optional site-wide default, deliberately absent from the snippet above. Any element without its own wf-algolia-index, and without an ancestor carrying one, falls back to it. |
Tracking
| Attribute | Default | What it does |
|---|---|---|
| off | Enables Algolia Insights click and conversion tracking. Only the exact string true turns it on. | |
| off | Persists the Insights user token in a cookie. Left off, tracking stays cookieless. | |
| waits | Set it to granted and events send straight away. Left off, the script waits for your consent banner. Also gates personalized recommendations. |
Turning data-insights on does not start tracking. The script binds its
listeners and then sends nothing, and writes no Insights cookie, until your
consent banner calls:
WfAlgolia.setInsightsConsent(true);
Call it with false to stop again. Anything a visitor did before they agreed is
discarded rather than held back and sent afterwards, so consenting never
backfills their earlier activity. WfAlgolia.hasInsightsConsent() tells you
where things stand.
If your site already has a legal basis to track, add
data-insights-consent="granted" and events flow without the call.
This gate also covers personalized recommendations. The
recommended-for-you model reads a visitor identifier, so it waits for the same
consent and stays hidden until it arrives. That is true even when
data-insights is off: personalization and event tracking are separate
features, and you can use either one on its own, but both wait here. See
the recommendation section.
Link destinations
| Attribute | Default | What it does |
|---|---|---|
| on | Restricts where search results can send a visitor. Only the exact string true turns it on. | |
| none | Comma-separated list of addresses allowed in addition to your own site. Only read when the above is on. |
Install search on a site today and the restriction starts on, so results reach your own site and nothing else until you add addresses. Sites installed before 2026-09-09 keep whatever they had: nothing changes underneath a site that is already live.
If your records are meant to link outward, to a directory or a job board for example, turn it off on the app's Install page and save. The app writes this attribute for you; you should not need to edit the tag by hand.
Add the addresses you want reachable alongside your own site:
data-restrict-origins="true"
data-allowed-origins="https://shop.example.com,https://docs.example.com"
Three things are true whenever the restriction is on:
- Your own site is always allowed. Relative links in your records keep working without listing anything, and turning the restriction on with an empty list locks results to your own site.
- Email and phone links are never affected.
mailto:andtel:hand off to a mail or phone app rather than a web address, so the list has nothing to say about them. - Images follow the same rule. A record image served from an address you have not listed will not load.
List exact addresses, and they must be https://. An http:// address is
refused when you save: a cleartext destination is a downgrade your visitors
cannot see. There are no wildcards either: *.example.com is not a value, and
https://example.com does not cover https://shop.example.com.
A blocked link is reported in the browser console, so open it if something you
expected to see has stopped appearing.
The app writes both attributes for you when you set the restriction on the Install page. They are documented here so you can recognise them in your page source, not so you can add them by hand.
Timing
| Attribute | Default | What it does |
|---|---|---|
250 | Milliseconds after the last keystroke before querying. | |
data-debounce, else 150 | Debounce for the autocomplete dropdown only. |
The script reads data-autocomplete-debounce first. If it is absent it uses
data-debounce. Only if both are absent does it use 150. So setting
data-debounce="400" also slows the autocomplete to 400ms unless you set the
autocomplete value explicitly.
Class names
| Attribute | Default | What it does |
|---|---|---|
is-active | Class added to a selected filter item. | |
is-hidden | Class added to filter items hidden behind "show more". |
Both exist so the script can drive classes you have already styled in Webflow rather than imposing its own.
Result rendering
| Attribute | Default | What it does |
|---|---|---|
30 | Words per snippet. Floored at 1; a non-numeric value falls back to 30. | |
* | Comma-separated fields to snippet, or * for all. | |
mark | Element wrapping highlighted matches. |
data-highlight-tag is checked against a tag-name pattern. Anything that does
not match silently reverts to mark — there is no warning, so a typo looks like
the attribute was ignored.
Notes that catch people out
Head is where the app puts it, and that is correct. The script does no work
when it loads: it registers a callback on Webflow's ready queue with
Webflow.push() and reads your elements only once Webflow says the page is
ready. Head or Footer makes no difference to that.
Booleans are string comparisons. data-insights and data-insights-cookie
are on only when the value is exactly true. "TRUE", "1" and "yes" are all
off. data-insights-consent works the same way but on a different word: only
granted opens the gate, so a typo leaves it closed rather than tracking
without consent.
Related
- Install the script
- Attribute reference — the
wf-algolia-*attributes you put on elements - CSS hooks