--- title: Autocomplete description: Configure Luma's search-as-you-type dropdown — the types it shows, request pacing, the built-in design and its tokens, and the hooks for your own code. slug: luma/widgets/autocomplete docKind: reference hub: luigisbox-ai --- 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 `integration/autocomplete/_config.ts`: ```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](/concepts/domain-model/#surfaces-and-widgets); 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](/discovery/fields/) to return, `filters` a [filter expression](/discovery/filters/). | | `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 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-` 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.`, else the field's name. ## Your own markup Set `dom: 'light'` and override `autocomplete-box` and `autocomplete-result-default` — see [Templates](/luma/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. ## Hooks 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 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 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 - [Search](/discovery/search/#autocomplete) — the request autocomplete sends - [Search results](/luma/widgets/search/) — the page "Show all products" leads to