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

@navsi.ai/sdk

v1.0.9

Published

React SDK for Navsi AI chatbot - Ask and Navigate modes

Readme

@navsi.ai/sdk - Navsi AI Chatbot SDK

AI-powered chatbot SDK for websites with Ask & Navigate modes.

⚠️ Note: This package is part of the navsi-integrated monorepo.

Installation (for external users)

npm install @navsi.ai/sdk
# or
yarn add @navsi.ai/sdk
# or
pnpm add @navsi.ai/sdk

For Next.js projects, ensure next is installed (optional peer dependency):
pnpm add next (or use your existing Next.js app).

Quick Start

Zero-config styling — All widget styles are auto-injected at runtime. You do not need to import any CSS file.

import { ChatbotProvider, ChatbotWidget } from '@navsi.ai/sdk';

function App() {
  return (
    <ChatbotProvider
      apiKey="YOUR_API_KEY"
      serverUrl="wss://your-server.com/ws"
    >
      <YourApp />
      <ChatbotWidget />
    </ChatbotProvider>
  );
}

Overriding Default Styles

The SDK auto-injects its styles in a <style> tag at the top of <head>. Any CSS you add in your own stylesheet will automatically take precedence. All widget classes are prefixed navsi-chatbot-*.

/* Example: custom toggle button */
.navsi-chatbot-toggle {
  background: #e11d48;
  box-shadow: 0 4px 16px rgba(225, 29, 72, 0.4);
}

/* Example: custom chat window size */
.navsi-chatbot-window {
  width: 420px;
  height: 600px;
}

Available CSS Classes

| Class Name | Element | | ------------------------------------ | ------------------------------------ | | .navsi-chatbot-container | Root fixed-position container | | .navsi-chatbot-toggle | Floating open/close button | | .navsi-chatbot-window | Chat window panel | | .navsi-chatbot-header | Window header bar | | .navsi-chatbot-header-left | Header left section (title + status) | | .navsi-chatbot-title | Header title text | | .navsi-chatbot-status | Connection status text | | .navsi-chatbot-clear | "Clear" chat button | | .navsi-chatbot-mode-toggle | Ask/Action mode toggle container | | .navsi-chatbot-mode-button | Individual mode button | | .navsi-chatbot-mode-active | Active mode button | | .navsi-chatbot-lang-toggle | Language toggle container | | .navsi-chatbot-lang-button | Individual language button | | .navsi-chatbot-lang-active | Active language button | | .navsi-chatbot-messages | Messages scroll area | | .navsi-chatbot-message | Individual message wrapper | | .navsi-chatbot-message-user | User message bubble | | .navsi-chatbot-message-assistant | Assistant message bubble | | .navsi-chatbot-message-content | Message content (markdown) | | .navsi-chatbot-message-paragraph | Paragraph inside assistant message | | .navsi-chatbot-message-list | Bullet list inside assistant message | | .navsi-chatbot-message-list-item | List item inside assistant message | | .navsi-chatbot-welcome | Welcome screen container | | .navsi-chatbot-welcome-icon | Welcome emoji icon | | .navsi-chatbot-welcome-text | Welcome message text | | .navsi-chatbot-welcome-hint | Welcome hint/subtitle | | .navsi-chatbot-input-area | Input area container | | .navsi-chatbot-input | Text input field | | .navsi-chatbot-send-button | Send button | | .navsi-chatbot-voice-button | Voice input button | | .navsi-chatbot-voice-button-active | Voice button while recording | | .navsi-chatbot-stop-button | Stop execution button | | .navsi-chatbot-error | Error banner | | .navsi-chatbot-error-close | Error dismiss button | | .navsi-chatbot-voice-error | Voice error message | | .navsi-chatbot-voice-transcript | Live voice transcript | | .navsi-chatbot-voice-indicator | Header voice indicator | | .navsi-chatbot-banner | Execution status banner | | .navsi-chatbot-pill | Progress step pill | | .navsi-chatbot-progress-container | Progress bar wrapper | | .navsi-chatbot-progress-bar | Progress bar track | | .navsi-chatbot-progress-fill | Progress bar fill | | .navsi-chatbot-typing | Typing dots indicator |

CSS Custom Properties

You can also set these CSS variables on .navsi-chatbot-container (or let the theme config set them automatically):

| Variable | Default | Description | | ----------------------- | ----------------- | ------------------------------------- | | --navsi-primary | #2563eb | Primary brand colour | | --navsi-primary-hover | #1d4ed8 | Primary hover colour | | --navsi-bg | #ffffff | Window background | | --navsi-text | #1f2937 | Text colour | | --navsi-font | System font stack | Font family | | --navsi-radius | 12px | Border radius (window, bubbles) | | --navsi-radius-sm | 6px | Small border radius (inputs, buttons) | | --navsi-window-width | 360px | Chat window width | | --navsi-window-height | 520px | Chat window height | | --navsi-button-size | 56px | Toggle button size |

With Configuration Fetching

For a complete setup with widget configuration from your server:

import React, { useState, useEffect } from 'react';
import { ChatbotProvider, ChatbotWidget } from '@navsi.ai/sdk';
import type { FlatWidgetConfig } from '@navsi.ai/shared';

function App() {
  const [widgetConfig, setWidgetConfig] = useState<FlatWidgetConfig | null>(null);
  const [configError, setConfigError] = useState<string | null>(null);

  const API_KEY = import.meta.env.VITE_NAVSI_API_KEY || process.env.REACT_APP_NAVSI_API_KEY;
  const API_BASE = import.meta.env.VITE_NAVSI_API_URL || process.env.REACT_APP_NAVSI_API_URL || 'https://api.example.com';
  
  // Convert HTTP URL to WebSocket URL
  const getWebSocketUrl = (httpUrl: string): string => {
    const url = new URL(httpUrl);
    const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
    return `${wsProtocol}//${url.host}${url.pathname.replace(/\/$/, '')}/ws`;
  };
  const WS_URL = getWebSocketUrl(API_BASE);

  useEffect(() => {
    fetch(`${API_BASE}/api/sdk/config`, {
      headers: { 'x-api-key': API_KEY },
    })
      .then((r) => {
        if (!r.ok) throw new Error(`Failed to fetch config: ${r.status}`);
        return r.json();
      })
      .then((data) => {
        if (data?.config && typeof data.config === 'object') {
          setWidgetConfig(data.config as FlatWidgetConfig);
        }
      })
      .catch((err) => {
        console.error('Failed to load widget config:', err);
        setConfigError(err.message);
        // Widget will still work with default config
      });
  }, []);

  return (
    <ChatbotProvider
      apiKey={API_KEY}
      serverUrl={WS_URL}
      config={widgetConfig}
    >
      <YourApp />
      <ChatbotWidget />
    </ChatbotProvider>
  );
}

Next.js (App Router)

Use a Client Component to wrap your app with the chatbot and provide a Next.js navigation adapter so the AI can navigate between pages:

  1. Create a client component (e.g. app/ClientProviders.tsx) with 'use client' at the top.
  2. Use useRouter() and usePathname() from next/navigation, and useNextRouterAdapter(router, pathname) from @navsi.ai/sdk.
  3. Wrap your app in ChatbotProvider (with navigationAdapter) and render ChatbotWidget.
  4. Set NEXT_PUBLIC_NAVSI_API_KEY and NEXT_PUBLIC_NAVSI_API_URL in .env.local (WebSocket URL is derived from the API URL).
// app/ClientProviders.tsx
'use client';

import { useRouter, usePathname } from 'next/navigation';
import { ChatbotProvider, ChatbotWidget, useNextRouterAdapter } from '@navsi.ai/sdk';

function getWebSocketUrl(httpUrl: string): string {
  const url = new URL(httpUrl);
  const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
  return `${wsProtocol}//${url.host}${url.pathname.replace(/\/$/, '')}/ws`;
}

export function ClientProviders({ children }: { children: React.ReactNode }) {
  const router = useRouter();
  const pathname = usePathname();
  const adapter = useNextRouterAdapter(router, pathname);

  const apiKey = process.env.NEXT_PUBLIC_NAVSI_API_KEY ?? '';
  const apiUrl = process.env.NEXT_PUBLIC_NAVSI_API_URL ?? 'http://localhost:3001';
  const serverUrl = getWebSocketUrl(apiUrl);

  return (
    <ChatbotProvider apiKey={apiKey} serverUrl={serverUrl} navigationAdapter={adapter} routes={['/', '/products', '/cart']}>
      {children}
      <ChatbotWidget />
    </ChatbotProvider>
  );
}

In your root app/layout.tsx, wrap your app with <ClientProviders>{children}</ClientProviders> (or nest it inside your layout so the widget is available on all pages).

Features

Ask Mode

  • Natural language Q&A about your website
  • Context-aware responses based on current page
  • Powered by Gemini AI

Navigate Mode

  • AI-guided navigation through your website
  • Automatic form filling
  • Multi-step task completion

Configuration Options

interface ChatbotProviderProps {
  // Required
  apiKey: string;              // Your API key from the admin dashboard
  serverUrl: string;            // WebSocket server URL (e.g., 'wss://api.example.com/ws')
  
  // Optional
  config?: FlatWidgetConfig | null;  // Widget config fetched from /api/sdk/config
  options?: Partial<WidgetConfig>;   // Additional widget configuration (e.g. voiceLanguage: 'hi-IN')
  navigationAdapter?: NavigationAdapter;  // Custom navigation adapter (defaults to memory)
  serverActions?: ServerAction[];    // Server-side actions the AI can execute
  routes?: string[];                // List of available routes (for AI context)
  debug?: boolean;                  // Enable debug logging
  autoConnect?: boolean;            // Auto-connect WebSocket on mount (default: true)
  children: React.ReactNode;       // Your app components
}

Widget Configuration

The config prop accepts a flat widget configuration object fetched from your server:

interface FlatWidgetConfig {
  headerTitle?: string;
  welcomeMessage?: string;
  inputPlaceholder?: string;
  showModeToggle?: boolean;
  defaultMode?: 'ask' | 'navigate';
  defaultOpen?: boolean;
  /** BCP-47 language for voice input, output, and AI responses (e.g. 'hi-IN' for Hindi) */
  voiceLanguage?: string;
  theme?: {
    primaryColor?: string;
    secondaryColor?: string;
    backgroundColor?: string;
    textColor?: string;
    fontFamily?: string;
    borderRadius?: number;
    darkMode?: boolean;
    position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
  };
}

Voice language (e.g. Hindi)

Set voiceLanguage to a BCP-47 locale (e.g. 'hi-IN' for Hindi) to:

  • Use that language for speech recognition (mic input)
  • Use that language for speech synthesis (AI reply read aloud)
  • Have the AI respond in that language (e.g. Hindi in Devanagari)

Example:

<ChatbotProvider
  apiKey={API_KEY}
  serverUrl={WS_URL}
  options={{ voiceLanguage: 'hi-IN' }}
>
  <ChatbotWidget />
</ChatbotProvider>

You can also pass voiceLanguage in the config object from your API. Browser support for Hindi (and other locales) depends on the client; Chrome supports hi-IN for both recognition and synthesis.

Server Actions

Register server-side actions that the AI can execute:

const serverActions = [
  {
    id: 'add-to-cart',
    name: 'Add to Cart',
    description: 'Add a product to the shopping cart',
    parameters: [
      { name: 'productId', type: 'string', required: true },
      { name: 'quantity', type: 'number', required: false, defaultValue: 1 },
    ],
    handler: async (params, context) => {
      // Your logic here
      return { success: true, data: { message: 'Added to cart!' } };
    },
  },
];

<ChatbotProvider 
  apiKey="YOUR_API_KEY"
  serverUrl="wss://your-server.com/ws"
  serverActions={serverActions}
>

Hooks

useChatbot

Access chatbot state and controls:

import { useChatbot } from '@navsi.ai/sdk';

function MyComponent() {
  const { 
    isConnected,
    mode,
    setMode,
    sendMessage,
    messages 
  } = useChatbot();
}

useWebSocket

Access WebSocket connection state:

import { useWebSocket } from '@navsi.ai/sdk';

function ConnectionStatus() {
  const { isConnected, isReconnecting } = useWebSocket();
  
  return <div>Status: {isConnected ? 'Connected' : isReconnecting ? 'Reconnecting' : 'Disconnected'}</div>;
}

useActionExecution

Track action execution progress:

import { useActionExecution } from '@navsi.ai/sdk';

function ProgressBar() {
  const { progress } = useActionExecution();
  
  return progress ? (
    <div>Step {progress.current + 1} of {progress.total}</div>
  ) : null;
}

Environment Variables

For production deployments, use environment variables:

# Vite (recommended)
VITE_NAVSI_API_KEY=your_api_key_here
VITE_NAVSI_API_URL=https://api.example.com

# Create React App
REACT_APP_NAVSI_API_KEY=your_api_key_here
REACT_APP_NAVSI_API_URL=https://api.example.com

# Next.js
NEXT_PUBLIC_NAVSI_API_KEY=your_api_key_here
NEXT_PUBLIC_NAVSI_API_URL=https://api.example.com

Important: Never commit API keys to version control. Use environment variables or secure configuration services.

Troubleshooting

Widget doesn't connect

  1. Check that serverUrl is correct (use wss:// for HTTPS, ws:// for HTTP)
  2. Verify your API key is valid
  3. Check browser console for WebSocket connection errors
  4. Ensure CORS is configured on your server

Configuration not loading

  1. Verify the /api/sdk/config endpoint returns valid JSON
  2. Check that the x-api-key header is included in the request
  3. Widget will fall back to default config if fetch fails

Actions not working

  1. Ensure navigationAdapter is provided if using React Router or similar
  2. Check that DOM elements have proper data-chatbot-action attributes
  3. Enable debug={true} to see detailed logs

Development

# From monorepo root
pnpm --filter @navsi.ai/sdk dev     # Watch mode
pnpm --filter @navsi.ai/sdk build   # Build
pnpm --filter @navsi.ai/sdk lint    # Lint

License

MIT