Pre-launch API. The concepts described here are settled, but the API shape is not: request and response fields, parameters and defaults can still change. Build against it, and talk to your Luigi's Box contact before you put an integration into production.
The autocomplete widget opens a dropdown under your existing search input as the shopper types. It does not replace the input or the form: picking a product or category follows its link, and Enter, a query suggestion or “Show all products” submit your own search form.
It attaches to every input matching _global.inputSelector, including inputs created after
the page loads and inputs inside shadow roots.
Configuration
Section titled “Configuration”integration/autocomplete/_config.ts:
export default { surface: 'lbs_search_main', types: [ { type: 'query', size: 4 }, { type: 'product', size: 7, fields: ['@title', 'url', 'image_url', 'price'] }, { type: 'category', size: 4 }, { type: 'brand', size: 3 }, ],};| Key | Default | |
|---|---|---|
surface | — | Required. A search surface; autocomplete sends it the partial query. |
types | — | Required. One request per entry, in parallel. type is the object type (query for query suggestions), size the number of results, fields the fields to return, filters a filter expression. |
minChars | 0 | The shortest phrase that sends a request. An empty phrase never does. |
instantChars | 3 | A phrase up to this length is requested on each keystroke |
debounceMs | 300 | A longer phrase is requested once typing pauses this long… |
maxWaitMs | 800 | …but at least this often while the shopper keeps typing |
dom | shadow | shadow: Luma’s own design, isolated from your CSS. light: the dropdown is a regular element your CSS styles. |
hostClass, hostId | — | With dom: 'light', a class and an ID put on the dropdown |
alignTo | The visible search field | What the dropdown lines up under. A CSS selector names an ancestor of the input; input uses the input itself. |
A phrase answered once on the page — after a backspace, or retyped — shows again without a request.
The built-in design
Section titled “The built-in design”With dom: 'shadow', the dropdown is a full panel: query suggestions as pills, other types
as titled lists, the first product large in its own column, the next six as cards, and
“Show all products” at the foot. On a phone it opens as a full-screen sheet with a tab per
type.
It takes its colours, font and corner radius from your page. Override any of them:
| Key | |
|---|---|
tokens | Design values: font, fg, bg, accent, radius, muted, line, soft, tint, tintStrong, onAccent, ok, radiusRow, radiusTile. For example { "accent": "#1a73e8", "font": "Inter, sans-serif" }. The same values are CSS custom properties --lbx-<name> on :host, for style-autocomplete.css. |
accentFrom | A selector of an element of yours whose colour becomes the accent — its background, else its text colour |
hero | The first product. variant: image (default, a large picture) or spec (a small picture and up to four specFields as label and value rows). badgeField: a field shown as a pill on the picture. |
productLayout | grid (default, two columns of cards) or list (rows) |
productFields | Fields shown on product cards, each optional: availability (text, or true / a positive number for “In stock”), category, oldPrice (struck through), meta (a second line in the list layout), price |
emptyState | When nothing matches: tryQueries, phrases offered instead; browse, links as { "title", "url" }; fallback, a fixed product search shown apart as { "query", "size" }. A help box with a phone number shows when the translation autocomplete.help.phone is set. |
Field labels in spec rows come from the translation autocomplete.specs.<field>, else the
field’s name.
Your own markup
Section titled “Your own markup”Set dom: 'light' and override autocomplete-box and autocomplete-result-default — see
Templates. Your site’s CSS then applies, and the integration’s
style-autocomplete.css goes into the document instead of the shadow root.
In your template, mark “Show all products” with data-lbx-all and bind its href to
allHref. It is the dropdown’s one Tab stop; the options are reached with the arrow keys.
Set in autocomplete/_init.ts, for your own code that reacts to the dropdown:
| Hook | Called |
|---|---|
onOpen() | When the dropdown opens |
onClose(reason) | When it closes. reason is one of select, enter, escape, back, blur, outside, navigate, empty, hidden, api. |
onSelect(r) | When the shopper picks a result |
onReady({ close, reposition }) | Once the widget has started, with controls for your own code |
Your existing suggestions
Section titled “Your existing suggestions”Put CSS that hides your site’s own suggestion dropdown in autocomplete/style-host.css. It
applies only once Luma’s dropdown has started, so a browser where it cannot start keeps
yours.
Requirements
Section titled “Requirements”The dropdown uses the browser’s Popover API. Without it — Safari before 17, Firefox before 125 — the widget does not start and your own suggestions remain.
See also
Section titled “See also”- Search — the request autocomplete sends
- Search results — the page “Show all products” leads to
Was this page helpful?
Thanks.