Skip to main content

Text search

This is the widget's main flow: the user types in natural language, the backend runs semantic search + conversational ranking, and the widget renders the results with guided filters, AI response and top products.

How it works

  1. The user types in the SearchInput component. The input is a <textarea> (not <input>) to allow long, multi-line queries.
  2. On Enter or submit, the widget calls:
    • GET /api/widget/search?q=… when no cart is wired in.
    • POST /api/widget/search with a JSON body when cart.enabled = true (includes cartContext).
  3. The SearchResponse is applied to the WidgetContext and the results grid, guided filters, top products and AI response are rendered.

Defined at WidgetSearchController.java:73 (GET) and WidgetSearchController.java:114 (POST).

Endpoint

GET/api/widget/search
# Query parameter is "q" (not "query"). limit defaults to 10, max 50.
curl "https://api.neuroon.ai/api/widget/search?q=running%20shoes&limit=10" \
-H "X-Widget-Token: $WIDGET_TOKEN"
POST/api/widget/search
curl -X POST https://api.neuroon.ai/api/widget/search \
-H "X-Widget-Token: $WIDGET_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "running shoes",
"limit": 10,
"filters": { "categories": ["sports"], "priceMin": 50, "priceMax": 200 },
"cartContext": { /* … */ }
}'

POST uses query and cartContext in the body (SearchRequestDTO.java:25); GET uses ?q= (WidgetSearchController.java:74). limit defaults to 10, maximum 50.

Response

SearchResponse (SearchResponseDTO):

FieldDescription
guidedFiltersDynamic question cards generated by the AI.
aiResponseAIResponseBox with the conversational answer.
topProductsHighlighted carousel at the top of the results page.
clarification, buyersGuide, kit, followUp, comparison, recommendationsComponents specific to each turn type.
cartAction, quickRepliesCart-aware actions and quick reply chips.

Input behavior

  • Ghost textinline suggestion (Tab to accept). Computed from the last result of the /api/widget/suggest endpoint (not suggestions). See features/suggestions.
  • Debounce — the suggestions dropdown debounces ~300 ms.
  • Mobile — minimum font-size: 16px to avoid iOS auto-zoom.

No persistent state

Each init() starts with a fresh searchLogId. If you need continuity across pages (so the widget remembers the conversation), the backend already emits a conversationId on SearchResponse that the widget reuses on subsequent requests while the session is alive.

Further reading