npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

product-agent-widget

v1.0.42

Published

A reusable React Voice Search Widget component library that supports both text and voice search, with customizable themes and positioning.

Readme

React Voice Search Widget

A production-grade, reusable React Voice Search Widget component library that developers can easily integrate into their apps. It supports text and voice search, flexible positioning, theming, and extensive customization.

This project is structured so that the root index.tsx serves as the main entry point for the package, exporting all necessary components and types. The repository also includes a complete demo application (App.tsx) that imports from the entry point to showcase functionality.

Features

  • Dual Input Modes: Supports both standard text input and voice search via the Web Speech API.
  • Flexible Positioning: Can be rendered inline within the page flow or as a floating widget in any corner (top-left, top-right, bottom-left, bottom-right).
  • Dynamic Results Dropdown: Shows search results, Q&A-style text responses, loading states, and errors in a clean dropdown.
  • Contextual Responses: Renders different UI components based on the pageType prop (search list, product Q&A, cart action response).
  • Context-Aware Actions: Can pass page-specific context (like a product ID) to your API for intelligent, stateful interactions (e.g., "add this to my cart").
  • Highly Customizable:
    • Theming: Comes with light and dark themes.
    • Custom Icons: Allows you to replace the default search and microphone icons with your own React components.
  • Developer-Friendly API: Simple props for connecting to your API, handling events (loading, response, error), and capturing user selections.
  • Built-in Debouncing: Optimizes API calls by debouncing user input, reducing server load.
  • Accessible: Includes ARIA labels and proper focus management.
  • Self-Contained: Designed to be a drop-in component with minimal setup.

Installation

npm install react-voice-search-widget

Note: You must publish the package to NPM under this name or a name of your choosing.

Building the Package

To build the package from source, run the following commands:

# Install development dependencies
npm install

# Build the project (compiles TS to JS in the /dist folder)
npm run build

Usage

Here are a few examples of how to integrate the VoiceSearchWidget into your application.

Basic Inline Widget

This is the simplest way to use the widget, perfect for a search page.

import React from 'react';
import { VoiceSearchWidget } from 'react-voice-search-widget';

const MySearchPage = () => {
  const handleSelect = (item) => {
    console.log('User selected:', item);
    // e.g., navigate(`/products/${item.id}`);
  };

  return (
    <div>
      <h2>Search Our Products</h2>
      <VoiceSearchWidget
        apiUrl="https://api.example.com/search"
        pageType="search"
        position="inline"
        placeholder="Search for products..."
        onResultSelect={handleSelect}
      />
    </div>
  );
};

Floating Widget (Bottom-Right)

To make the widget accessible from anywhere in your app, use a floating position.

import React from 'react';
import { VoiceSearchWidget } from 'react-voice-search-widget';

const App = () => {
  return (
    <div>
      {/* Your application content */}
      
      <VoiceSearchWidget
        apiUrl="https://api.example.com/search"
        position="bottom-right"
        theme="dark"
        placeholder="Ask anything..."
      />
    </div>
  );
};

Props API

The widget can be configured with the following props:

| Prop | Type | Default | Description | | ---------------- | ---------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------- | | apiUrl | string | (required) | The API endpoint to send the search query to. | | position | 'inline' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'inline' | Determines the positioning of the widget. | | pageType | 'search' | 'product' | 'faq' | 'cart' | string | 'search' | Context for the API call. 'search' renders a list. 'product'/'faq' render rich-text. 'cart' renders a text response. | | placeholder | string | 'Search...' | Placeholder text for the input field. | | theme | 'light' | 'dark' | 'light' | Sets the color scheme for the widget. | | maxResults | number | 10 | The maximum number of results to fetch for 'search' pageType. | | apiContext | Record<string, any> | {} | An object containing page-specific context (e.g., { productId: '123' }) to be sent with the API request. | | className | string | '' | Optional CSS classes to apply to the root element for custom styling. | | searchIcon | React.ReactNode | (default icon) | A custom React node to replace the default search icon. | | micIcon | React.ReactNode | (default icon) | A custom React node to replace the default microphone icon. | | onLoading | (query: string) => void | undefined | Callback function that fires when an API request starts. | | onResponse | (response: any) => void | undefined | Callback function that fires when an API response is successfully received. | | onError | (error: Error) => void | undefined | Callback function that fires when an API request fails. | | onResultSelect | (item: SearchResult) => void | undefined | Callback function that fires when a user clicks on a search result item. |

Providing Page Context

For the widget to perform context-aware actions (like adding the current product to a cart), you must provide it with information about the page it's on. Use the apiContext prop for this.

Example: Product Page

On a product page, you can pass the product's ID and name. Your backend can then use this data to fulfill the user's request.

import React from 'react';
import { VoiceSearchWidget } from 'react-voice-search-widget';

const ProductPage = ({ product }) => {
  // product = { id: 'XYZ-123', name: 'Galaxy Projector' }

  return (
    <div>
      <h1>{product.name}</h1>
      {/* ...product details... */}

      <VoiceSearchWidget
        apiUrl="https://api.example.com/product-actions"
        pageType="product"
        placeholder="Ask a question about this product..."
        apiContext={{ productId: product.id, productName: product.name }}
      />
    </div>
  );
};

When a user says "add to cart", the API will receive a payload like: { "query": "add to cart", "context": { "productId": "XYZ-123", "productName": "Galaxy Projector" } }

Customizing Icons

You can easily replace the default search and microphone icons by passing your own React components (or any ReactNode) to the searchIcon and micIcon props. This is useful for matching the widget to your application's design system.

Example

import React from 'react';
import { VoiceSearchWidget } from 'react-voice-search-widget';
import { MyCustomSearchIcon, MyCustomMicIcon } from './MyIcons';

const CustomizedWidget = () => (
  <VoiceSearchWidget
    apiUrl="https://api.example.com/search"
    placeholder="Search with custom icons..."
    searchIcon={<MyCustomSearchIcon className="h-5 w-5 text-purple-500" />}
    micIcon={<MyCustomMicIcon className="h-5 w-5 text-orange-500" />}
  />
);

Voice Recognition

  • The voice search functionality is powered by the browser's native Web Speech API.
  • If the API is not supported by the user's browser, the microphone icon will be hidden automatically, and the widget will gracefully fall back to being a text-only search bar.
  • The component requests microphone permission when the user first clicks the mic icon.