@yectra/nexosearch-widget
v1.0.3
Published
Embeddable React search widget
Readme
NexoSearch Widget
Embeddable search widget for third‑party sites. Ships ES and UMD bundles and isolates styles via Shadow DOM for safer embedding.
Development
npm run dev– start local dev servernpm run build:lib– build library bundlesnpm run build– type‑check then buildnpm run preview– preview the production build
Dev environment vars (optional): VITE_SEARCH_API_URL, VITE_SEARCH_API_KEY.
Embed via Script Tag (UMD)
- Include bundle(s) from
dist/:
<script src="/dist/nexosearch-widget.umd.js"></script>- Add a container and initialize:
<div id="nexo-search-root"></div>
<script>
NexoSearch.init({
target: '#nexo-search-root',
apiUrl: 'https://texcoms.azure-api.net/search',
apiKey: '<YOUR_API_KEY>',
width: 640,
dropdownWidth: 640,
dropdownPosition: 'right',
searchTrigger: 'change',
minQueryLength: 3,
theme: 'light'
});
</script>Embed via ES Module
import { init } from '/dist/nexosearch-widget.es.js';
init({
target: '#nexo-search-root',
apiUrl: 'https://texcoms.azure-api.net/search',
apiKey: '<YOUR_API_KEY>',
});Config Options
- target: CSS selector for mount container (required).
- apiKey: API key string (required for protected endpoints).
- apiUrl: Base search API URL. Defaults to Texcoms endpoint when not provided.
- theme: 'light' | 'dark' for MUI theme in the Shadow DOM. Default 'light'.
- width: Number or CSS size for input container width.
- dropdownWidth: Number or CSS size for dropdown width. Falls back to
width. - dropdownPosition: 'left' | 'right'. When 'left', dropdown uses
right: 0. When 'right', dropdown usesleft: 0. - searchTrigger: 'change' | 'enter'. 'change' fetches as you type; 'enter' fetches only on Enter.
- minQueryLength: Minimum trimmed characters before fetching. Default 3.
- dropdownColor: Color for dropdown panel background. Default
#fff. - backgroundColor: Color for the search input background. Default
#fff. - borderRadius: Number radius (px) for the search input. Default
4. - borderColor: Color for the search input border. Default
#ccc. - placeholderText: Placeholder string for the search input. Default
"Search...".
Behavior Notes
- Dropdown overlays the page, doesn’t affect layout, and closes on outside click without clearing results.
- Results are grouped by category with tabs and can be scrolled up to the viewport height.
- In 'enter' mode, consider adding UX hints (“Press Enter to search”).
Troubleshooting
- If dev server fails, ensure
vite.config.tslib.entrymatches the file:src/widget.tsx. - When embedding on sites with strict CSP, host the bundle yourself and add appropriate script allowances.
Use in React via npm
Install the package:
npm install @yectra/nexosearch-widget
# or: yarn add @yectra/nexosearch-widget
# or: pnpm add @yectra/nexosearch-widgetBasic usage (programmatic init inside a React component):
import { useEffect } from 'react';
import { init } from '@yectra/nexosearch-widget';
export default function SearchWidgetSection() {
useEffect(() => {
init({
target: '#nexo-search-root',
apiUrl: 'https://texcoms.azure-api.net/search',
apiKey: '<YOUR_API_KEY>',
width: 640,
dropdownWidth: 640,
dropdownPosition: 'right', // 'left' pins right:0; 'right' pins left:0
searchTrigger: 'change', // or 'enter'
minQueryLength: 3,
theme: 'light',
});
}, []);
return <div id="nexo-search-root" />;
}TypeScript (optional):
import type { WidgetConfig } from '@yectra/nexosearch-widget';
const config: WidgetConfig = { target: '#root', apiKey: '...' };Wrapper component pattern (keeps your JSX clean):
import { useEffect, useRef } from 'react';
import { init } from '@yectra/nexosearch-widget';
export function NexoSearchWrapper(props: Parameters<typeof init>[0]) {
const elRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (elRef.current) {
init({ target: '#' + elRef.current.id, ...props });
}
}, [props]);
return <div id="nexo-search-root" ref={elRef} />;
}Notes:
- The widget renders inside a Shadow DOM for style isolation; no extra CSS import is needed.
- You can place the mount
divanywhere in your React tree; the widget manages its own React root.
