Widget · Overview
The Neuroon widget is an embeddable component that adds AI-powered semantic search to any online store. It integrates with a single <script> and isolates itself from the host theme via Shadow DOM in open mode, avoiding CSS and JavaScript collisions with your template.
It is designed for server-rendered integrations (WordPress, Magento, .NET, custom platforms). Any HTML page that can render a <script> and a <div> can embed it.
What it solves
| Capability | Detail |
|---|---|
| Semantic search | Users type in natural language, not keywords. The backend re-ranks with a conversational agent that queries the shop catalog. |
| Voice search | Web Speech API + endpoint POST /api/widget/search/audio. Graceful fallback if the browser doesn't support voice. |
| Image search | Image upload or camera capture. Endpoint POST /api/widget/search/visual. |
| Inline AI assistant | Conversational answer + guided filters (single-choice, multi-choice) generated by the LLM. |
| Comparator | Up to 4 products with pros/cons, winner and match score. Endpoint GET /api/widget/compare. |
| Cart-aware | When the host configures cart, the widget sends a cart snapshot with every POST /api/widget/search to personalize results (cross-sell, remember shipping destinations, etc.). |
| Cross-sell | Complementary recommendations on top of the current cart (POST /api/widget/cart/cross-sell). |
| Buyers guide | Contextual buying guides generated by AI when the query needs prior education. |
| Kit builder | Build bundles with related products (savings calculated by the backend). |
| Follow-up | Conversational follow-up within the same conversationId. |
Stack
Preact 10.19 ─┐
TypeScript │
Tailwind v4 ├──► Bundle ~262 KB (gzip ~65 KB)
Vite 5 │
Framer Motion ─┘
- Preact instead of React to reduce bundle size (~3 KB vs ~45 KB).
- Shadow DOM in
openmode — the host can inspect the tree but theme styles do not leak in. Implemented inwidget/src/index-preact.tsx(createShadowDOM). - CSS inlined in the bundle via
import widgetStyles from './tailwind.css?inline'— no extra network request for styles.
How it works
- The CDN loader registers
window.NeuroonWidgetand, when it finds a<script>withdata-token, automatically callsinit()(auto-init inwidget/src/index-preact.tsx). createShadowDOM()runscontainer.attachShadow({ mode: 'open' }), injects the inline CSS and creates two sub-containers:.neuroon-widget(Preact tree) and#neuroon-portal-root(modals and overlays).renderWidget()resolves the theme (auto/light/dark), appliesStyleOverrides, registers theprefers-color-schemelistener and mounts the Preact tree inside the shadow root.- Every backend request carries the
X-Widget-Tokenheader (validated byWidgetTokenAuthenticationFilter.java).
Multi-instance
The widget supports several instances on the same page (one init() per container). Internally a Map<containerId, ShadowDOMState> keeps theme, global events and cleanup per instance:
window.NeuroonWidget.getInstanceIds() // ['neuroon-widget-1', 'neuroon-widget-2']
window.NeuroonWidget.destroy('#header-search') // destroys only that instance
window.NeuroonWidget.destroy() // destroys all
Further reading
- Installation — script tag, SRI, recommended CSP policy.
- Configuration — every option (
data-attrsandNeuroonWidgetConfig). - Theming —
--nrn-*variables andStyleOverrides. - Widget events — what it emits and what it listens for from the host.
- Cart integration — how the host feeds the snapshot.