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 search widget takes over your existing search results page. It renders into an element of your page, hides your own listing while its own is shown, and leaves the rest of the page — header, breadcrumbs, footer — as it is. Your search form keeps submitting to the same URL.
Configuration
Section titled “Configuration”integration/search/_config.ts:
export default { urlMatch: '^/search$', queryParam: 'q', anchor: '#search-results', position: 'prepend', surface: 'lbs_search_main', size: 24, facets: ['brand', 'color', 'lbx:price'], sorts: ['', 'lbx:price:asc', 'lbx:price:desc'], fields: ['@title', 'url', 'image_url', 'price', 'brand'], quick: [{ type: 'category', size: 4 }],};Which pages
Section titled “Which pages”| Key | Default | |
|---|---|---|
urlMatch | Any page with queryParam | A regular expression on the URL’s path |
queryParam | — | The query parameter holding the search query. Without it, the first capture group of urlMatch is the query: ^/search/([^/]+)$. |
For URLs a regular expression cannot describe, set functions in search/_init.ts:
| Hook | |
|---|---|
active(url) | Whether this URL is a search page |
readQuery(url) | The query on this URL |
A search page without a query is left to your site.
Search-only keys
Section titled “Search-only keys”| Key | Default | |
|---|---|---|
quick | — | Other object types shown above the results, such as category or brand tiles. One request per entry: { "type", "size", "fields" }. |
inPlaceQuery | true | A new query from your search form while on the search page renders in place, with a new history entry and no page load. Set false when parts of your search page outside the listing are server-rendered and must follow the query, or when your page-view analytics must fire per search. |
prefetchWhileTyping | true | Once the phrase typed in your search input settles, its results are fetched, so Enter shows them at once |
prefetchDelayMs | 300 | How long the phrase must stay unchanged first |
prefetchMaxAgeMs | 120000 | How long a result fetched while typing is used |
prerenderWhileTyping | false | In Chrome and Edge, also prerender the search page of the settled phrase, so Enter from another page shows a page already rendered. Each settled phrase costs your server a page render, and your analytics count a page view unless they wait for the prerendered page to be shown. |
prerenderEagerness | immediate | immediate or eager |
Listing keys
Section titled “Listing keys”Search results and category pages are the same listing and share these keys.
Placement
Section titled “Placement”| Key | Default | |
|---|---|---|
anchor | — | Required. A CSS selector of the element the listing is placed relative to, or a list of candidates, most specific first |
position | — | Required. prepend or append inside the anchor, before or after it |
rootClass | — | Classes of yours put on the listing’s element, so it sits in your own grid |
settleMs | — | Wait until the anchor stops changing for this long — for frameworks that re-render after load |
reserveSelector | The anchor | The element that reserves the listing’s remembered height while it loads, so the page does not jump |
holdTimeoutMs | 4000 | If the listing has not rendered by then, your own is shown instead |
showTitle | — | Show the query, or the category name, as a heading |
What is requested
Section titled “What is requested”| Key | Default | |
|---|---|---|
surface | — | Required. A search surface for search, a collection surface for category pages |
size | — | Required. Results per page: the first page, and each “show more” |
fields | The surface’s | Fields the tiles need. Fewer fields, smaller responses. |
baseFilters | — | A filter expression always applied, combined with the shopper’s filters |
Facets, sorting, flags
Section titled “Facets, sorting, flags”| Key | Default | |
|---|---|---|
facets | — | Required. Fields offered as filters, in sidebar order. Numeric fields become range sliders. See Facets. |
facetSize | 50 | Values per text facet |
emptyValues | false | With a filter applied, also list the values the unfiltered page has, marked empty, for sites that grey them out. Costs one more request per query or category. |
facetGroups | All open | open: which groups start expanded — true, false, or the first N, optionally per viewport min-width ({ "0": false, "1024": 3 }). search: facets whose group gets a search box over its values. searchMin (10): the fewest values that get one. |
rangeSteps | 1 | The step of a range slider, by facet: { "lbx:price": 10 } |
sorts | — | Required. Sort options as field:direction; '' is relevance. Labels come from the translations search.sorts. |
flags | — | On/off filters of your own: [{ "id": "in-stock", "filter": { "in_stock": { "eq": true } } }]. Labels come from search.flags.<id>. |
facetsApply | instant | How changes inside the filter drawer apply: instant, or staged until its apply button is pressed. Per viewport min-width too: { "0": "staged", "768": "instant" }. |
The filter drawer is your markup: data-lbx-drawer="open" on the control that opens it,
data-lbx-drawer-panel on the panel, data-lbx-drawer="apply" and
data-lbx-drawer="close" on its buttons.
Facet values carry no counts.
Behaviour
Section titled “Behaviour”| Key | Default | |
|---|---|---|
restoreOnBack | true | Back from a product restores the listing — every page loaded — at the tile the shopper followed, then refreshes it in the background |
prefetchNextPage | true | The next page is fetched as the shopper nears the end, so “show more” appends at once |
contentVisibility | false | Tiles out of view skip style, layout and paint, which roughly halves a long list’s re-render. Leave it off when a tile draws outside its box — a hover panel, a badge hanging over the edge — or contains a position: fixed element. |
Set in _init.ts or _widget.ts:
| Hook | |
|---|---|
onRender({ route, query, total, shown, page, url }) | After each render — to keep your document title in step, for example |
The URL
Section titled “The URL”The listing’s state is in the URL, so a filtered page can be shared, bookmarked and reached
with Back. Luma’s own parameters start with lbx.: lbx.sort, lbx.flag, and
lbx.<field> for each facet. “Show more” does not change the URL, and a listing always opens
on its first page.
See also
Section titled “See also”- Category pages — the same listing for collections
- Templates —
search-*templates and their scope - Behaviour and fallbacks — when your own listing is shown instead
Was this page helpful?
Thanks.