React components
@askdialog/dialog-react ships ready-made components on top of @askdialog/dialog-sdk. Use it when you want a fast, themed UI without building it from scratch.
Requires React 19+.
Install
Section titled “Install”npm install @askdialog/dialog-sdk @askdialog/dialog-reactImport the stylesheet once at the entry of your app:
import '@askdialog/dialog-react/style.css'Initialize the SDK client
Section titled “Initialize the SDK client”Instantiate the SDK once (typically at module scope or in a top-level provider), then pass it to each component.
import { Dialog, type SimplifiedProduct } from '@askdialog/dialog-sdk'
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'en', callbacks: { addToCart: async ({ productId, quantity, variantId }) => { // Hit your cart API, refresh your UI }, getProduct: async (productId, variantId): Promise<SimplifiedProduct> => { // Return your product in SimplifiedProduct shape }, },})See the SDK reference for all constructor options.
DialogProductBlock
Section titled “DialogProductBlock”The headline component. Drop it on a product page to render AI-generated question suggestions and the assistant entry point.
import { DialogProductBlock } from '@askdialog/dialog-react'
function ProductPage({ product }) { return ( <DialogProductBlock client={client} productId={product.id} productTitle={product.title} selectedVariantId={product.currentVariantId} /> )}| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
client |
Dialog |
Yes | - | SDK instance from new Dialog(...). |
productId |
string |
Yes | - | The current product’s ID. Must match the ID in your catalog. |
productTitle |
string |
Yes | - | Display name for the product. |
selectedVariantId |
string |
No | - | The currently selected variant (size, color, etc.). Pass it whenever the user changes variant so the assistant has context. |
enableInput |
boolean |
No | true |
Show the input field under the suggestions. Set to false if you want suggestions only. |
DialogInput
Section titled “DialogInput”A standalone input field for asking a free-form question. Useful as an entry point on pages without a single product context (homepage, blog, collection).
import { DialogInput } from '@askdialog/dialog-react'
function Homepage() { return ( <DialogInput client={client} productId="homepage" productTitle="Homepage" /> )}| Prop | Type | Required | Description |
|---|---|---|---|
client |
Dialog |
Yes | SDK instance. |
productId |
string |
Yes | A stable identifier for the context (e.g. "homepage", "collection-summer"). |
productTitle |
string |
Yes | A human-readable label for the context. |
Storefront search
Section titled “Storefront search”Ready-made components that power an AI-ranked product search on a custom or headless React storefront, the same search behind the Shopify AI Search blocks. They wrap the SDK search controller (createSearchController): debounce, request cancellation, stale-response protection, pagination and search attribution analytics all come from the SDK, so the components only render and route.
import { DialogSearchBar, DialogSearchResults, useDialogSearch,} from '@askdialog/dialog-react'
function SearchPage() { const { controller, state } = useDialogSearch({ client })
return ( <> <DialogSearchBar controller={controller} placeholder="Search products..." /> <DialogSearchResults controller={controller} state={state} /> </> )}useDialogSearch
Section titled “useDialogSearch”Creates one search controller per hook instance and disposes it on unmount. Returns { controller, state }: pass both to the components below. state.status is idle / loading / success / empty / error.
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
client |
Dialog |
Yes | - | SDK instance. |
surface |
SearchSurface |
No | 'search_page' |
Where results are displayed, for analytics. |
navigate |
(url, hit) => void |
No | - | Router adapter called after selection attribution (e.g. (url) => router.push(url)). Omit it to let the cards’ <a href> links navigate natively. |
debounceMs |
number |
No | 250 |
Keystroke debounce. |
hitsPerPage |
number |
No | 12 |
Results per page. |
locale |
string |
No | - | Locale forwarded to the search request. |
DialogSearchBar
Section titled “DialogSearchBar”Search input: typing runs a debounced search, submitting (Enter) searches immediately.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
controller |
SearchController |
Yes | - | From useDialogSearch. |
placeholder |
string |
No | - | Input placeholder text. |
autoFocus |
boolean |
No | false |
Focus the input on mount. |
submitAriaLabel |
string |
No | 'Search' |
Accessible label of the submit button. |
DialogSearchResults
Section titled “DialogSearchResults”Floating results panel portaled to document.body and anchored under the bar: place it right after DialogSearchBar. It renders the controller states; a successful search shows a scrollable list of product cards plus pagination. Each card links to the product page and records search attribution (impressions, select on click and middle-click) automatically.
| Prop | Type | Required | Description |
|---|---|---|---|
controller |
SearchController |
Yes | From useDialogSearch. |
state |
SearchControllerState |
Yes | From useDialogSearch. |
locale |
string |
No | BCP 47 locale used to format the card prices (browser default when omitted). |
DialogSearchPagination is rendered by DialogSearchResults and is also exported for custom layouts (same controller + state props).
Typical layout
Section titled “Typical layout”A common setup:
<DialogInput>on the homepage as a discovery entry point.<DialogProductBlock>on every PDP, between the gallery and the description.- Variant change handler that updates the
selectedVariantIdprop.
Theming
Section titled “Theming”The components inherit the theme passed to the SDK constructor. Update brand colors, fonts, CTA shape, and component-specific font sizes:
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'en', theme: { backgroundColor: '#ffffff', primaryColor: '#000000', ctaTextColor: '#ffffff', ctaBorderType: 'rounded', capitalizeCtas: false, fontFamily: 'Inter, sans-serif', title: { fontSize: '18px', color: '#1a1a1a' }, description: { fontSize: '14px', color: '#666666' }, content: { fontSize: '14px', color: '#333333' }, }, callbacks: { /* ... */ },})Next steps
Section titled “Next steps”- SDK reference: full API for
client. - Tracking: SDK custom: wire side-cart and checkout tracking.
- Add-to-cart issues: keeping your UI in sync.
