Quick Search Widget (React)
A React component widget that enables users to perform real-time product searches with instant results, enhancing product discoverability and conversion.
Use this library when you want to render a widget and you are using React and JSX in your project.
This widget library is version 0.1.11 and the API can change. Please specify exact version when installing.
Installation
Install @recombee/quick-search-widget-react@0.1.11
and
recombee-js-api-client
packages using your preferred NPM package manager.
This example is using pnpm
.
pnpm add @recombee/quick-search-widget-react@0.1.11 recombee-js-api-client
Always remember to apply the default CSS file distributed alongside the widget library, as shown in the examples.
Client Initialization
The widget loads recommendation data using Recombee API Client. Here is how to initialize the client with necessary configuration for a specific database:
import { class ApiClient
Client for sending requests to Recombee and getting repliesApiClient } from "recombee-js-api-client";
const const DATABASE_ID: "[database-id]"
DATABASE_ID = "[database-id]";
const const PUBLIC_TOKEN: "[database-public-token]"
PUBLIC_TOKEN = "[database-public-token]";
const const REGION: "[database-region]"
REGION = "[database-region]";
export const const apiClient: ApiClient
apiClient = new new ApiClient(databaseId: string, publicToken: string, options?: ApiClientOptions): ApiClient
ApiClient(const DATABASE_ID: "[database-id]"
DATABASE_ID, const PUBLIC_TOKEN: "[database-public-token]"
PUBLIC_TOKEN, {
region?: string | undefined
region: const REGION: "[database-region]"
REGION,
});
The Database Public Token can be found in the Admin UI Database Settings Page.
The widget also needs to be provided a createRequest
function, which
instantiates a client request class to define which data to pull from the
database. Use Scenario ID which can be found on Admin GUI
Database Scenarios Page.
Quick Search widget requires the createRequest
function to return a Batch
Request. For a basic case of single search request, always wrap it in a
batch.
import { type type CreateRequestFunction = (options: {
searchQuery: string;
isFullScreen?: boolean;
}) => Request
CreateRequestFunction } from "@recombee/quick-search-widget-react";
import { class Batch
Batch processing allows you to submit any sequence of requests within a single HTTPS request.
Any type of request from this SDK may be used in the Batch, and the Batch may combine different types of requests arbitrarily as well.
Using Batch requests can be beneficial in situations such as synchronizing the catalog of items or uploading historical interaction data,
as sending the data in Batch is considerably faster than sending the individual requests (thanks to optimizations and reducing network and HTTPS overhead).Batch, class SearchItems
Full-text personalized search. The results are based on the provided `searchQuery` and also on the user's past interactions (purchases, ratings, etc.) with the items (items more suitable for the user are preferred in the results).
All the string and set item properties are indexed by the search engine.
This endpoint should be used in a search box on your website/app. It can be called multiple times as the user is typing the query in order to get the most viable suggestions based on the current state of the query, or once after submitting the whole query.
The returned items are sorted by relevance (the first item being the most relevant).
Besides the recommended items, also a unique `recommId` is returned in the response. It can be used to:
- Let Recombee know that this search was successful (e.g., user clicked one of the recommended items). See [Reported metrics](https://docs.recombee.com/admin_ui.html#reported-metrics).
- Get subsequent search results when the user scrolls down or goes to the next page. See [Recommend Next Items](https://docs.recombee.com/api.html#recommend-next-items).
It is also possible to use POST HTTP method (for example in the case of a very long ReQL filter) - query parameters then become body parameters.SearchItems, class SearchItemSegments
Full-text personalized search that returns Segments from a Segmentation. The results are based on the provided `searchQuery` and also on the user's past interactions (purchases, ratings, etc.).
Based on the used Segmentation, this endpoint can be used for example for:
- Searching within categories or brands
- Searching within genres or artists
For example if the user is searching for "iPhone" this endpoint can return "cell phones" category.
You need to set the used Segmentation the Admin UI in the Scenario settings prior to using this endpoint.
The returned segments are sorted by relevance (first segment being the most relevant).
It is also possible to use POST HTTP method (for example in case of very long ReQL filter) - query parameters then become body parameters.SearchItemSegments } from "recombee-js-api-client";
const const createRequest: CreateRequestFunction
createRequest: type CreateRequestFunction = (options: {
searchQuery: string;
isFullScreen?: boolean;
}) => Request
CreateRequestFunction = ({ searchQuery: string
searchQuery }) => {
return new new Batch(requests: Request[], optional?: {
distinctRecomms?: boolean;
}): Batch
Batch(
[
new new SearchItems(userId: string, searchQuery: string, count: number, optional?: {
scenario?: string;
cascadeCreate?: boolean;
returnProperties?: boolean;
includedProperties?: string[];
filter?: string;
booster?: string;
logic?: string | object;
expertSettings?: {
[key: string]: unknown;
};
returnAbGroup?: boolean;
}): SearchItems
SearchItems(userId, searchQuery: string
searchQuery, 5, {
scenario?: string | undefined
Scenario defines a particular search field in your user interface.scenario: "search-items",
cascadeCreate?: boolean | undefined
If the user does not exist in the database, returns a list of non-personalized search results and creates the user in the database. This allows, for example, rotations in the following recommendations for that user, as the user will be already known to the system.cascadeCreate: true,
returnProperties?: boolean | undefined
With `returnProperties=true`, property values of the recommended items are returned along with their IDs in a JSON dictionary. The acquired property values can be used to easily display the recommended items to the user.returnProperties: true,
}),
new new SearchItemSegments(userId: string, searchQuery: string, count: number, optional?: {
scenario?: string;
cascadeCreate?: boolean;
filter?: string;
booster?: string;
logic?: string | object;
expertSettings?: {
[key: string]: unknown;
};
returnAbGroup?: boolean;
}): SearchItemSegments
SearchItemSegments(userId, searchQuery: string
searchQuery, 5, {
scenario?: string | undefined
Scenario defines a particular application of recommendations. It can be, for example, "homepage", "cart", or "emailing".scenario: "search-categories",
cascadeCreate?: boolean | undefined
If the user does not exist in the database, returns a list of non-personalized recommendations and creates the user in the database. This allows, for example, rotations in the following recommendations for that user, as the user will be already known to the system.cascadeCreate: true,
}),
],
{
distinctRecomms?: boolean | undefined
distinctRecomms: true,
},
);
};
Providing User ID
Each visitor of your website should be identified by a user identificator
(userId
) to correlate user activity and deliver best possible
recommendation performance. The userId
should preferrably originate from
your user's account details when the user is authenticated or as some
session-persistent random ID when they are anonymous. The SDK provides
utility which generates random user id and saves it to a cookie to cover the
latter case:
import { type type CreateRequestFunction = (options: {
searchQuery: string;
isFullScreen?: boolean;
}) => Request
CreateRequestFunction } from "@recombee/quick-search-widget-react";
import { class Batch
Batch processing allows you to submit any sequence of requests within a single HTTPS request.
Any type of request from this SDK may be used in the Batch, and the Batch may combine different types of requests arbitrarily as well.
Using Batch requests can be beneficial in situations such as synchronizing the catalog of items or uploading historical interaction data,
as sending the data in Batch is considerably faster than sending the individual requests (thanks to optimizations and reducing network and HTTPS overhead).Batch, class SearchItems
Full-text personalized search. The results are based on the provided `searchQuery` and also on the user's past interactions (purchases, ratings, etc.) with the items (items more suitable for the user are preferred in the results).
All the string and set item properties are indexed by the search engine.
This endpoint should be used in a search box on your website/app. It can be called multiple times as the user is typing the query in order to get the most viable suggestions based on the current state of the query, or once after submitting the whole query.
The returned items are sorted by relevance (the first item being the most relevant).
Besides the recommended items, also a unique `recommId` is returned in the response. It can be used to:
- Let Recombee know that this search was successful (e.g., user clicked one of the recommended items). See [Reported metrics](https://docs.recombee.com/admin_ui.html#reported-metrics).
- Get subsequent search results when the user scrolls down or goes to the next page. See [Recommend Next Items](https://docs.recombee.com/api.html#recommend-next-items).
It is also possible to use POST HTTP method (for example in the case of a very long ReQL filter) - query parameters then become body parameters.SearchItems, class SearchItemSegments
Full-text personalized search that returns Segments from a Segmentation. The results are based on the provided `searchQuery` and also on the user's past interactions (purchases, ratings, etc.).
Based on the used Segmentation, this endpoint can be used for example for:
- Searching within categories or brands
- Searching within genres or artists
For example if the user is searching for "iPhone" this endpoint can return "cell phones" category.
You need to set the used Segmentation the Admin UI in the Scenario settings prior to using this endpoint.
The returned segments are sorted by relevance (first segment being the most relevant).
It is also possible to use POST HTTP method (for example in case of very long ReQL filter) - query parameters then become body parameters.SearchItemSegments } from "recombee-js-api-client";
import { class PersistentUserID
PersistentUserID } from "@recombee/carousel-widget-react";
let let userId: string | undefined
userId: string | undefined;
if (authenticatedUserId) {
let userId: string | undefined
userId = authenticatedUserId;
} else {
let userId: string | undefined
userId = class PersistentUserID
PersistentUserID.PersistentUserID.getId(): string
getId();
}
const const createRequest: CreateRequestFunction
createRequest: type CreateRequestFunction = (options: {
searchQuery: string;
isFullScreen?: boolean;
}) => Request
CreateRequestFunction = ({ searchQuery: string
searchQuery }) => {
return new new Batch(requests: Request[], optional?: {
distinctRecomms?: boolean;
}): Batch
Batch(
[
new new SearchItems(userId: string, searchQuery: string, count: number, optional?: {
scenario?: string;
cascadeCreate?: boolean;
returnProperties?: boolean;
includedProperties?: string[];
filter?: string;
booster?: string;
logic?: string | object;
expertSettings?: {
[key: string]: unknown;
};
returnAbGroup?: boolean;
}): SearchItems
SearchItems(let userId: string | undefined
userId, searchQuery: string
searchQuery, 5, {
scenario?: string | undefined
Scenario defines a particular search field in your user interface.scenario: "search-items",
cascadeCreate?: boolean | undefined
If the user does not exist in the database, returns a list of non-personalized search results and creates the user in the database. This allows, for example, rotations in the following recommendations for that user, as the user will be already known to the system.cascadeCreate: true,
returnProperties?: boolean | undefined
With `returnProperties=true`, property values of the recommended items are returned along with their IDs in a JSON dictionary. The acquired property values can be used to easily display the recommended items to the user.returnProperties: true,
}),
new new SearchItemSegments(userId: string, searchQuery: string, count: number, optional?: {
scenario?: string;
cascadeCreate?: boolean;
filter?: string;
booster?: string;
logic?: string | object;
expertSettings?: {
[key: string]: unknown;
};
returnAbGroup?: boolean;
}): SearchItemSegments
SearchItemSegments(let userId: string | undefined
userId, searchQuery: string
searchQuery, 5, {
scenario?: string | undefined
Scenario defines a particular application of recommendations. It can be, for example, "homepage", "cart", or "emailing".scenario: "search-categories",
cascadeCreate?: boolean | undefined
If the user does not exist in the database, returns a list of non-personalized recommendations and creates the user in the database. This allows, for example, rotations in the following recommendations for that user, as the user will be already known to the system.cascadeCreate: true,
}),
],
{
distinctRecomms?: boolean | undefined
distinctRecomms: true,
},
);
};
Basic Example
The widget in this example uses the DefaultItem component to render each recommendation in a consistent layout.
The resulting widget is inserted into the element specified by the
container
field.
Values of the recommended items - such as title, image URL, or link URL - are
obtained from the API response and accessed via props.result?.values
.
Ensure that returnProperties: true is set in the request, and optionally use includedProperties to control which item properties are returned.
import {
const QuickSearchWidget: React.FunctionComponent<QuickSearchWidgetProps>
Quick Search widget componentQuickSearchWidget,
function addRecommIdQueryParam(url: string, recommId: string | undefined): string
Utility function to append `recombee_recomm_id` parameter to an url string.
For usage in widget template to construct item link URL.addRecommIdQueryParam,
const DefaultInput: ((props: {
state: QuickSearchWidgetState;
inputProps?: {
placeholder?: string;
};
}) => React.JSX.Element) & {
...;
}
DefaultInput,
const DefaultItem: ((props: {
href?: string;
image?: React.ReactNode;
primaryContent?: React.ReactNode;
secondaryContent?: React.ReactNode;
highlightedContent?: React.ReactNode;
}) => React.JSX.Element) & {
...;
}
DefaultItem,
const ItemImage: React.FunctionComponent<ItemImageProps>
Item image componentItemImage,
function SearchIcon(): React.JSX.Element
SearchIcon,
function CloseIcon(): React.JSX.Element
CloseIcon,
} from "@recombee/quick-search-widget-react";
import "@recombee/quick-search-widget-react/dist/styles.css";
export default () => {
return (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex justify-center p-12">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="@container-normal">
<const QuickSearchWidget: React.FunctionComponent<QuickSearchWidgetProps>
Quick Search widget componentQuickSearchWidget
WidgetConfigurationBase<CR extends (...args: any[]) => Request = CreateRequestFunction>.apiClient: ApiClient
Instance of Recombee JS API Client. See
{@link
file://./#client-initialization Example
}
.apiClient={const apiClient: ApiClient
apiClient}
WidgetConfigurationBase<CR extends (...args: any[]) => Request = CreateRequestFunction>.createRequest: CreateRequestFunction
Request factory function. See
{@link
file://./#client-initialization Quick Example
}
or visit
{@link
file:///api API Reference
}
for overview of available requests.createRequest={const createRequest: CreateRequestFunction
createRequest}
minSearchCharactersCount: number
Minimum length of search query for search request to be sent.minSearchCharactersCount={3}
desktopMediaQuery: string
CSS media query specifing when the widget should behave as displayed on
desktop. By default, widget behaves as mobile-first, filling entire
device screen with results dropdown.desktopMediaQuery="(min-width: 1000px)"
type InputComponent: React.FC<InputProps>
Component responsible for rendering the widget input.InputComponent={(props: InputProps
props) => (
<React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form React.HTMLAttributes<T>.className?: string | undefined
className="flex w-[400px] text-[#374040]">
<const DefaultInput: ((props: {
state: QuickSearchWidgetState;
inputProps?: {
placeholder?: string;
};
}) => React.JSX.Element) & {
...;
}
DefaultInput
state: QuickSearchWidgetState
state={props: InputProps
props.state: QuickSearchWidgetState
state}
inputProps?: {
placeholder?: string;
} | undefined
inputProps={{ placeholder?: string | undefined
placeholder: `Search for "table"...` }}
/>
</React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form>
)}
type TriggerComponent: React.FC<TriggerProps>
Component responsible for rendering the widget trigger on mobile devices.TriggerComponent={(props: TriggerProps
props) => (
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
{...props: TriggerProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.triggerProps: {
ref: (element: HTMLElement | null) => void;
onClick: () => void;
}
Properties to be passed to the trigger button of a mobile widget.triggerProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex size-[38px] items-center justify-center rounded-sm bg-[#3bc4a1] text-white"
>
<function SearchIcon(): React.JSX.Element
SearchIcon />
</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>
)}
type DropdownComponent: React.FC<DropdownProps>
Component responsible for rendering the widget dropdown.DropdownComponent={(props: DropdownProps
props) => (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="mt-1 flex h-full max-h-full min-h-0 flex-col rounded-sm bg-white text-[#374040] shadow-2xl lg:h-auto lg:max-w-[900px] lg:min-w-[600px]">
{!props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.isDesktop: boolean
Indicates that the widget is displayed on desktop device.isDesktop && (
<React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form React.HTMLAttributes<T>.className?: string | undefined
className="flex items-center gap-2 p-2">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex-grow">
<const DefaultInput: ((props: {
state: QuickSearchWidgetState;
inputProps?: {
placeholder?: string;
};
}) => React.JSX.Element) & {
...;
}
DefaultInput
state: QuickSearchWidgetState
state={props: DropdownProps
props.state: QuickSearchWidgetState
state}
inputProps?: {
placeholder?: string;
} | undefined
inputProps={{ placeholder?: string | undefined
placeholder: `Search for "table"...` }}
/>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
{...props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.closeButtonProps: {
type: "button";
onClick: () => void;
onTouchEnd: () => void;
}
Properties to be passed to the close button of a mobile dropdown.closeButtonProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex size-[38px] items-center justify-center"
>
<function CloseIcon(): React.JSX.Element
CloseIcon />
</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>
</React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form>
)}
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex min-h-0 flex-grow flex-col">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="px-4 py-4 pb-2 text-sm font-semibold text-[#3f91ff]">
Results
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="overflow-auto p-2">
{props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.items: (index: number) => {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]
Getter for current results of the request batch. The `index` parameter
indicates an index of results in the Batch Request for which to return
items.items(0).Array<{ key: string; id: string; recommId: string; values: { [key: string]: any; }; itemProps: { tabIndex: number; "data-search-result-id"?: string | undefined; onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void; }; }>.map<React.JSX.Element>(callbackfn: (value: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}, index: number, array: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item) => (
<const DefaultItem: ((props: {
href?: string;
image?: React.ReactNode;
primaryContent?: React.ReactNode;
secondaryContent?: React.ReactNode;
highlightedContent?: React.ReactNode;
}) => React.JSX.Element) & {
...;
}
DefaultItem
React.Attributes.key?: React.Key | null | undefined
key={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.key: string
key}
href?: string | undefined
href={function addRecommIdQueryParam(url: string, recommId: string | undefined): string
Utility function to append `recombee_recomm_id` parameter to an url string.
For usage in widget template to construct item link URL.addRecommIdQueryParam(
`${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
link}`,
item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.recommId: string
recommId,
)}
image?: React.ReactNode
image={
<const ItemImage: React.FunctionComponent<ItemImageProps>
Item image componentItemImage
className?: string | undefined
Image wrapper class nameclassName="size-16 overflow-hidden rounded-lg"
src?: string | null | undefined
Image URLsrc={`${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
image}`}
width?: number | undefined
Image width in pixelswidth={600}
height?: number | undefined
Image height in pixelsheight={400}
/>
}
primaryContent?: React.ReactNode
primaryContent={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
product_title}
secondaryContent?: React.ReactNode
secondaryContent={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
category_top}
highlightedContent?: React.ReactNode
highlightedContent={`USD ${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
price}`}
{...item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
}
itemProps}
/>
))}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
)}
/>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
};
Custom Template
You can customize the appearance and behavior of the Quick Search Widget by overriding its individual components:
- DropdownComponent – Renders the dropdown containing search results.
- InputComponent – Handles the search input field where users type their queries.
- TriggerComponent – Controls how the widget is opened on mobile devices.
The example also demonstrates how to make the search form submittable to a
dedicated results page using a submit
button.
import {
const QuickSearchWidget: React.FunctionComponent<QuickSearchWidgetProps>
Quick Search widget componentQuickSearchWidget,
function addRecommIdQueryParam(url: string, recommId: string | undefined): string
Utility function to append `recombee_recomm_id` parameter to an url string.
For usage in widget template to construct item link URL.addRecommIdQueryParam,
function DefaultSpinner(props: {
className: string;
}): React.JSX.Element
DefaultSpinner,
const ItemImage: React.FunctionComponent<ItemImageProps>
Item image componentItemImage,
function SearchIcon(): React.JSX.Element
SearchIcon,
function CloseIcon(): React.JSX.Element
CloseIcon,
} from "@recombee/quick-search-widget-react";
import "@recombee/quick-search-widget-react/dist/styles.css";
export default () => {
return (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex justify-center p-12">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="@container-normal">
<const QuickSearchWidget: React.FunctionComponent<QuickSearchWidgetProps>
Quick Search widget componentQuickSearchWidget
WidgetConfigurationBase<CR extends (...args: any[]) => Request = CreateRequestFunction>.apiClient: ApiClient
Instance of Recombee JS API Client. See
{@link
file://./#client-initialization Example
}
.apiClient={const apiClient: ApiClient
apiClient}
WidgetConfigurationBase<CR extends (...args: any[]) => Request = CreateRequestFunction>.createRequest: CreateRequestFunction
Request factory function. See
{@link
file://./#client-initialization Quick Example
}
or visit
{@link
file:///api API Reference
}
for overview of available requests.createRequest={const createRequest: CreateRequestFunction
createRequest}
minSearchCharactersCount: number
Minimum length of search query for search request to be sent.minSearchCharactersCount={3}
typingDebounceDuration?: number | undefined
Maximum duration between keystrokes in milliseconds before search request
is made.typingDebounceDuration={1000}
desktopMediaQuery: string
CSS media query specifing when the widget should behave as displayed on
desktop. By default, widget behaves as mobile-first, filling entire
device screen with results dropdown.desktopMediaQuery="(min-width: 1000px)"
type InputComponent: React.FC<InputProps>
Component responsible for rendering the widget input.InputComponent={(props: InputProps
props) => (
<React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form
React.FormHTMLAttributes<HTMLFormElement>.method?: string | undefined
method="GET"
React.FormHTMLAttributes<HTMLFormElement>.action?: string | ((formData: FormData) => void | Promise<void>) | undefined
action="https://example.com/search"
React.FormHTMLAttributes<HTMLFormElement>.target?: string | undefined
target="_blank"
React.HTMLAttributes<T>.className?: string | undefined
className="flex w-[400px] gap-2 text-[#374040]"
>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="relative flex flex-grow overflow-hidden rounded-lg border border-[#d9dbdb]">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex size-[38px] items-center justify-center text-[#737979]">
<function SearchIcon(): React.JSX.Element
SearchIcon />
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
input
React.InputHTMLAttributes<HTMLInputElement>.name?: string | undefined
name="q"
React.InputHTMLAttributes<HTMLInputElement>.type?: React.HTMLInputTypeAttribute | undefined
type="text"
React.HTMLAttributes<T>.className?: string | undefined
className="block w-full outline-hidden"
React.InputHTMLAttributes<HTMLInputElement>.placeholder?: string | undefined
placeholder={`Search for "table"...`}
{...props: InputProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.inputProps: {
value: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
onClick: () => void;
ref: (element: HTMLElement | null) => void;
}
Properties to be passed to a input component.inputProps}
/>
{props: InputProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.isLoading: boolean
Boolean flag indicating that a request for new results is in flight.isLoading && (
<function DefaultSpinner(props: {
className: string;
}): React.JSX.Element
DefaultSpinner className: string
className="rb:absolute rb:top-2.25 rb:right-2.25 rb:h-5 rb:w-5" />
)}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
React.ButtonHTMLAttributes<HTMLButtonElement>.type?: "button" | "reset" | "submit" | undefined
type="submit"
React.HTMLAttributes<T>.className?: string | undefined
className="rounded-lg bg-[#3f91ff] px-5 py-2.5 text-sm font-medium text-white focus:ring-4 focus:ring-blue-300 focus:outline-hidden"
>
Search
</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>
</React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form>
)}
type TriggerComponent: React.FC<TriggerProps>
Component responsible for rendering the widget trigger on mobile devices.TriggerComponent={(props: TriggerProps
props) => (
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
{...props: TriggerProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.triggerProps: {
ref: (element: HTMLElement | null) => void;
onClick: () => void;
}
Properties to be passed to the trigger button of a mobile widget.triggerProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex size-[38px] items-center justify-center rounded-sm bg-[#3bc4a1] text-white"
>
<function SearchIcon(): React.JSX.Element
SearchIcon />
</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>
)}
type DropdownComponent: React.FC<DropdownProps>
Component responsible for rendering the widget dropdown.DropdownComponent={(props: DropdownProps
props) => (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="mt-1 flex h-full max-h-full min-h-0 flex-col rounded-sm bg-white text-[#374040] shadow-2xl lg:h-auto lg:max-w-[900px] lg:min-w-[600px]">
{!props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.isDesktop: boolean
Indicates that the widget is displayed on desktop device.isDesktop && (
<React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form React.HTMLAttributes<T>.className?: string | undefined
className="flex items-center gap-2 p-2">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex-grow">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="relative flex flex-grow overflow-hidden rounded-lg border border-[#d9dbdb]">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex size-[42px] items-center justify-center text-[#737979]">
<function SearchIcon(): React.JSX.Element
SearchIcon />
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
input
React.InputHTMLAttributes<HTMLInputElement>.type?: React.HTMLInputTypeAttribute | undefined
type="text"
React.HTMLAttributes<T>.className?: string | undefined
className="block w-full outline-hidden"
React.InputHTMLAttributes<HTMLInputElement>.placeholder?: string | undefined
placeholder="Search in docs..."
{...props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.inputProps: {
value: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
onClick: () => void;
ref: (element: HTMLElement | null) => void;
}
Properties to be passed to a input component.inputProps}
/>
{props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.isLoading: boolean
Boolean flag indicating that a request for new results is in flight.isLoading && (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="absolute top-2.5 right-2.5 h-5 w-5 animate-spin rounded-full border-2 border-dashed border-current text-[#d9dbdb] [--animate-spin:spin_3s_linear_infinite]" />
)}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
{...props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.closeButtonProps: {
type: "button";
onClick: () => void;
onTouchEnd: () => void;
}
Properties to be passed to the close button of a mobile dropdown.closeButtonProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex size-[38px] items-center justify-center"
>
<function CloseIcon(): React.JSX.Element
CloseIcon />
</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>
</React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form>
)}
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex min-h-0 flex-grow flex-col">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="px-4 py-4 pb-2 text-sm font-semibold text-[#3f91ff]">
Results
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="overflow-auto p-2">
{props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.items: (index: number) => {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]
Getter for current results of the request batch. The `index` parameter
indicates an index of results in the Batch Request for which to return
items.items(0).Array<{ key: string; id: string; recommId: string; values: { [key: string]: any; }; itemProps: { tabIndex: number; "data-search-result-id"?: string | undefined; onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void; }; }>.map<React.JSX.Element>(callbackfn: (value: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}, index: number, array: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item) => (
<React.JSX.IntrinsicElements.a: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>
a
React.Attributes.key?: React.Key | null | undefined
key={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.key: string
key}
React.AnchorHTMLAttributes<HTMLAnchorElement>.href?: string | undefined
href={function addRecommIdQueryParam(url: string, recommId: string | undefined): string
Utility function to append `recombee_recomm_id` parameter to an url string.
For usage in widget template to construct item link URL.addRecommIdQueryParam(
`${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
link}`,
item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.recommId: string
recommId,
)}
{...item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
}
itemProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex items-center gap-4 rounded-sm p-2 outline-hidden hover:bg-[#f7f7f7] focus:bg-[#f7f7f7]"
>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<const ItemImage: React.FunctionComponent<ItemImageProps>
Item image componentItemImage
className?: string | undefined
Image wrapper class nameclassName="size-16 overflow-hidden rounded-lg"
src?: string | null | undefined
Image URLsrc={`${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
image}`}
width?: number | undefined
Image width in pixelswidth={600}
height?: number | undefined
Image height in pixelsheight={400}
/>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="rb:flex-grow">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="rb:font-semibold rb:text-nowrap rb:text-ellipsis rb:overflow-hidden">
{item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
product_title}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="rb:text-[#737979] rb:text-nowrap rb:text-ellipsis rb:overflow-hidden">
{item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
category}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="rb:font-bold rb:text-[#3f91ff] rb:text-nowrap rb:text-ellipsis rb:overflow-hidden">{`USD ${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
price}`}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.a: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>
a>
))}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
)}
/>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
};
Multi-Type Search Results
You can use the Quick Search Widget to display multiple types of results. For example, showing not only items but also categories or brands using the Search Item Segments requests.
All search requests are sent together in a single Batch request.
import {
const QuickSearchWidget: React.FunctionComponent<QuickSearchWidgetProps>
Quick Search widget componentQuickSearchWidget,
function addRecommIdQueryParam(url: string, recommId: string | undefined): string
Utility function to append `recombee_recomm_id` parameter to an url string.
For usage in widget template to construct item link URL.addRecommIdQueryParam,
const DefaultInput: ((props: {
state: QuickSearchWidgetState;
inputProps?: {
placeholder?: string;
};
}) => React.JSX.Element) & {
...;
}
DefaultInput,
const DefaultItem: ((props: {
href?: string;
image?: React.ReactNode;
primaryContent?: React.ReactNode;
secondaryContent?: React.ReactNode;
highlightedContent?: React.ReactNode;
}) => React.JSX.Element) & {
...;
}
DefaultItem,
const ItemImage: React.FunctionComponent<ItemImageProps>
Item image componentItemImage,
function SearchIcon(): React.JSX.Element
SearchIcon,
function CloseIcon(): React.JSX.Element
CloseIcon,
} from "@recombee/quick-search-widget-react";
import "@recombee/quick-search-widget-react/dist/styles.css";
const const createRequest: CreateRequestFunction
createRequest: type CreateRequestFunction = (options: {
searchQuery: string;
isFullScreen?: boolean;
}) => Request
CreateRequestFunction = ({ searchQuery: string
searchQuery }) => {
return new new Batch(requests: Request[], optional?: {
distinctRecomms?: boolean;
}): Batch
Batch(
[
new new SearchItems(userId: string, searchQuery: string, count: number, optional?: {
scenario?: string;
cascadeCreate?: boolean;
returnProperties?: boolean;
includedProperties?: string[];
filter?: string;
booster?: string;
logic?: string | object;
expertSettings?: {
[key: string]: unknown;
};
returnAbGroup?: boolean;
}): SearchItems
SearchItems("userId", searchQuery: string
searchQuery, 5, {
scenario?: string | undefined
Scenario defines a particular search field in your user interface.scenario: "search",
cascadeCreate?: boolean | undefined
If the user does not exist in the database, returns a list of non-personalized search results and creates the user in the database. This allows, for example, rotations in the following recommendations for that user, as the user will be already known to the system.cascadeCreate: true,
returnProperties?: boolean | undefined
With `returnProperties=true`, property values of the recommended items are returned along with their IDs in a JSON dictionary. The acquired property values can be used to easily display the recommended items to the user.returnProperties: true,
}),
new new SearchItemSegments(userId: string, searchQuery: string, count: number, optional?: {
scenario?: string;
cascadeCreate?: boolean;
filter?: string;
booster?: string;
logic?: string | object;
expertSettings?: {
[key: string]: unknown;
};
returnAbGroup?: boolean;
}): SearchItemSegments
SearchItemSegments("userId", searchQuery: string
searchQuery, 5, {
scenario?: string | undefined
Scenario defines a particular application of recommendations. It can be, for example, "homepage", "cart", or "emailing".scenario: "search-brands",
cascadeCreate?: boolean | undefined
If the user does not exist in the database, returns a list of non-personalized recommendations and creates the user in the database. This allows, for example, rotations in the following recommendations for that user, as the user will be already known to the system.cascadeCreate: true,
}),
],
{
distinctRecomms?: boolean | undefined
distinctRecomms: true,
},
);
};
export default () => {
return (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex justify-center p-12">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="@container-normal">
<const QuickSearchWidget: React.FunctionComponent<QuickSearchWidgetProps>
Quick Search widget componentQuickSearchWidget
WidgetConfigurationBase<CR extends (...args: any[]) => Request = CreateRequestFunction>.apiClient: ApiClient
Instance of Recombee JS API Client. See
{@link
file://./#client-initialization Example
}
.apiClient={const apiClient: ApiClient
apiClient}
WidgetConfigurationBase<CR extends (...args: any[]) => Request = CreateRequestFunction>.createRequest: CreateRequestFunction
Request factory function. See
{@link
file://./#client-initialization Quick Example
}
or visit
{@link
file:///api API Reference
}
for overview of available requests.createRequest={const createRequest: CreateRequestFunction
createRequest}
minSearchCharactersCount: number
Minimum length of search query for search request to be sent.minSearchCharactersCount={3}
primaryResultsIndex?: number | undefined
Index of request in a batch from which the results are considered to be
navigable by arrow keys.primaryResultsIndex={0}
desktopMediaQuery: string
CSS media query specifing when the widget should behave as displayed on
desktop. By default, widget behaves as mobile-first, filling entire
device screen with results dropdown.desktopMediaQuery="(min-width: 1000px)"
type InputComponent: React.FC<InputProps>
Component responsible for rendering the widget input.InputComponent={(props: InputProps
props) => (
<React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form React.HTMLAttributes<T>.className?: string | undefined
className="flex w-[400px] text-[#374040]">
<const DefaultInput: ((props: {
state: QuickSearchWidgetState;
inputProps?: {
placeholder?: string;
};
}) => React.JSX.Element) & {
...;
}
DefaultInput
state: QuickSearchWidgetState
state={props: InputProps
props.state: QuickSearchWidgetState
state}
inputProps?: {
placeholder?: string;
} | undefined
inputProps={{ placeholder?: string | undefined
placeholder: `Search for "table"...` }}
/>
</React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form>
)}
type TriggerComponent: React.FC<TriggerProps>
Component responsible for rendering the widget trigger on mobile devices.TriggerComponent={(props: TriggerProps
props) => (
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
{...props: TriggerProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.triggerProps: {
ref: (element: HTMLElement | null) => void;
onClick: () => void;
}
Properties to be passed to the trigger button of a mobile widget.triggerProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex size-[38px] items-center justify-center rounded-sm bg-[#3bc4a1] text-white"
>
<function SearchIcon(): React.JSX.Element
SearchIcon />
</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>
)}
type DropdownComponent: React.FC<DropdownProps>
Component responsible for rendering the widget dropdown.DropdownComponent={(props: DropdownProps
props) => (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="mt-1 flex h-full max-h-full min-h-0 flex-col rounded-sm bg-white text-[#374040] shadow-2xl lg:h-auto lg:max-w-[900px] lg:min-w-[600px]">
{!props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.isDesktop: boolean
Indicates that the widget is displayed on desktop device.isDesktop && (
<React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form React.HTMLAttributes<T>.className?: string | undefined
className="flex items-center gap-2 p-2">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex-grow">
<const DefaultInput: ((props: {
state: QuickSearchWidgetState;
inputProps?: {
placeholder?: string;
};
}) => React.JSX.Element) & {
...;
}
DefaultInput
state: QuickSearchWidgetState
state={props: DropdownProps
props.state: QuickSearchWidgetState
state}
inputProps?: {
placeholder?: string;
} | undefined
inputProps={{ placeholder?: string | undefined
placeholder: `Search for "table"...` }}
/>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
{...props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.closeButtonProps: {
type: "button";
onClick: () => void;
onTouchEnd: () => void;
}
Properties to be passed to the close button of a mobile dropdown.closeButtonProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex size-[38px] items-center justify-center"
>
<function CloseIcon(): React.JSX.Element
CloseIcon />
</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button>
</React.JSX.IntrinsicElements.form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>
form>
)}
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex min-h-0 flex-col">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="px-4 py-4 pb-2 text-sm font-semibold text-[#3f91ff]">
Segments
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="overflow-auto p-2">
{props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.items: (index: number) => {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]
Getter for current results of the request batch. The `index` parameter
indicates an index of results in the Batch Request for which to return
items.items(1).Array<{ key: string; id: string; recommId: string; values: { [key: string]: any; }; itemProps: { tabIndex: number; "data-search-result-id"?: string | undefined; onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void; }; }>.map<React.JSX.Element>(callbackfn: (value: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}, index: number, array: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item) => (
<React.JSX.IntrinsicElements.a: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>
a
React.Attributes.key?: React.Key | null | undefined
key={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.key: string
key}
React.AnchorHTMLAttributes<HTMLAnchorElement>.href?: string | undefined
href={function addRecommIdQueryParam(url: string, recommId: string | undefined): string
Utility function to append `recombee_recomm_id` parameter to an url string.
For usage in widget template to construct item link URL.addRecommIdQueryParam(
`${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
link}`,
item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.recommId: string
recommId,
)}
{...item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
}
itemProps}
React.HTMLAttributes<T>.className?: string | undefined
className="flex items-center gap-2 rounded-sm p-2 text-nowrap outline-hidden hover:bg-[#f7f7f7] focus:bg-[#f7f7f7]"
>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex-grow">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="font-semibold">{item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.id: string
id}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.a: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>
a>
))}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="flex min-h-0 flex-grow flex-col">
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="px-4 py-4 pb-2 text-sm font-semibold text-[#3f91ff]">
Results
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className="overflow-auto p-2">
{props: DropdownProps
props.state: QuickSearchWidgetState
state.QuickSearchWidgetState.items: (index: number) => {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]
Getter for current results of the request batch. The `index` parameter
indicates an index of results in the Batch Request for which to return
items.items(0).Array<{ key: string; id: string; recommId: string; values: { [key: string]: any; }; itemProps: { tabIndex: number; "data-search-result-id"?: string | undefined; onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void; }; }>.map<React.JSX.Element>(callbackfn: (value: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}, index: number, array: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item) => (
<const DefaultItem: ((props: {
href?: string;
image?: React.ReactNode;
primaryContent?: React.ReactNode;
secondaryContent?: React.ReactNode;
highlightedContent?: React.ReactNode;
}) => React.JSX.Element) & {
...;
}
DefaultItem
React.Attributes.key?: React.Key | null | undefined
key={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.key: string
key}
href?: string | undefined
href={function addRecommIdQueryParam(url: string, recommId: string | undefined): string
Utility function to append `recombee_recomm_id` parameter to an url string.
For usage in widget template to construct item link URL.addRecommIdQueryParam(
`${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
link}`,
item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.recommId: string
recommId,
)}
image?: React.ReactNode
image={
<const ItemImage: React.FunctionComponent<ItemImageProps>
Item image componentItemImage
className?: string | undefined
Image wrapper class nameclassName="size-16 overflow-hidden rounded-lg"
src?: string | null | undefined
Image URLsrc={`${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
image}`}
width?: number | undefined
Image width in pixelswidth={600}
height?: number | undefined
Image height in pixelsheight={400}
/>
}
primaryContent?: React.ReactNode
primaryContent={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
product_title}
secondaryContent?: React.ReactNode
secondaryContent={item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
category_top}
highlightedContent?: React.ReactNode
highlightedContent={`USD ${item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.values: {
[key: string]: any;
}
values?.__type[string]: any
price}`}
{...item: {
key: string;
id: string;
recommId: string;
values: {
[key: string]: any;
};
itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
};
}
item.itemProps: {
tabIndex: number;
"data-search-result-id"?: string | undefined;
onKeyDown: (event: React.KeyboardEvent<HTMLInputElement | HTMLAnchorElement | HTMLDivElement>) => void;
}
itemProps}
/>
))}
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
)}
/>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
);
};
API Reference
QuickSearchWidget
Quick Search widget component
QuickSearchWidgetProps
Quick Search component configuration options
Properties
createRequest
Request factory function. See Quick Example or visit API Reference for overview of available requests.
onRecommResponse
Callback function allowing to intercept and inspect recommendation request+response made by widget.
import React from "react";
import { const CarouselWidget: React.FunctionComponent<CarouselWidgetProps>
Carousel widget React Component. See
{@link
CarouselWidgetProps
}
for
configuration options.CarouselWidget } from "@recombee/carousel-widget-react";
<const CarouselWidget: React.FunctionComponent<CarouselWidgetProps>
Carousel widget React Component. See
{@link
CarouselWidgetProps
}
for
configuration options.CarouselWidget
// ...ommited code...
WidgetConfigurationBase<CreateRequestFunction>.onRecommResponse?: WidgetRecommResponseCallback | undefined
Callback function allowing to intercept and inspect recommendation
request+response made by widget.
```tsx|-react
import React from "react";
import { CarouselWidget } from "@recombee/carousel-widget-react";
//onRecommResponse={({ recombeeRequest: Request
recombeeRequest, recombeeResponse: any
recombeeResponse }) => {
// use data from request and response for any purpose, i.e. internal tracking
}}
/>;
initialQuery
String to be prefilled into the search input
minSearchCharactersCount
Minimum length of search query for search request to be sent.
typingDebounceDuration
Maximum duration between keystrokes in milliseconds before search request is made.
primaryResultsIndex
Index of request in a batch from which the results are considered to be navigable by arrow keys.
InputComponent
Component responsible for rendering the widget input.
TriggerComponent
Component responsible for rendering the widget trigger on mobile devices.
DropdownComponent
Component responsible for rendering the widget dropdown.
desktopMediaQuery
CSS media query specifing when the widget should behave as displayed on desktop. By default, widget behaves as mobile-first, filling entire device screen with results dropdown.
QuickSearchWidgetState
Class exposing quick search widget state for use in custom templates
Properties
isDesktop
Indicates that the widget is displayed on desktop device.
reset
Resets the widget to its initial state
inputProps
Properties to be passed to a input component.
triggerProps
Properties to be passed to the trigger button of a mobile widget.
closeButtonProps
Properties to be passed to the close button of a mobile dropdown.
items
Getter for current results of the request batch. The index
parameter
indicates an index of results in the Batch Request for which to return
items.
isExpanded
Boolean flag indicating that the widget dropdown is open.
isLoading
Boolean flag indicating that a request for new results is in flight.
ItemImage
Item image component
ItemImageProps
Item Image properties
Properties
src
Image URL
missingImageSrc
URL of an image to display when the main image could not be loaded.
className
Image wrapper class name
imgClassName
Image class name
width
Image width in pixels
height
Image height in pixels
verticalAlignment
Image vertical alignment
horizontalAlignment
Image horizontal alignment
fittingAlgorithm
Image fitting algorithm
addRecommIdQueryParam
Utility function to append recombee_recomm_id
parameter to an url string.
For usage in widget template to construct item link URL.