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

@nexvio-ai/widget-js

v0.1.0

Published

Embeddable Nexvio chat widget custom element and React bindings.

Readme

Nexvio Widget JS

Embeddable JavaScript SDK that renders the Nexvio chat experience inside any web application. The package exposes two custom elements:

  • <nexvio-chat-widget> - Direct widget embed (for custom integrations)
  • <nexvio-chat-bot> - Floating chat button with animated widget (recommended)

Plus React bindings for developers who prefer declarative integrations.

Installation

pnpm add @nexvio-ai/widget-js

The package ships ESM, CJS, and type declarations. React bindings are exposed via the @nexvio-ai/widget-js/react subpath export.

Quick Start

Using <nexvio-chat-bot> (Recommended)

The easiest way to add a chat widget to your site is using <nexvio-chat-bot>, which provides a floating chat button and automatically manages the widget container.

import '@nexvio-ai/widget-js';

const chatbot = document.createElement('nexvio-chat-bot');
chatbot.setOptions({ publicKey: 'pk_test-123' });
document.body.append(chatbot);

React:

import { NexvioChatbot } from '@nexvio-ai/widget-js/react';

export function App() {
  return (
    <NexvioChatbot
      options={{
        publicKey: 'pk_test-123',
        onEvent: (event) => console.log(event.name, event.detail),
      }}
    />
  );
}

Using <nexvio-chat-widget> (Advanced)

For custom integrations where you want full control over the widget container, use <nexvio-chat-widget> directly.

import '@nexvio-ai/widget-js';

const widget = document.createElement('nexvio-chat-widget');
widget.setOptions({ publicKey: 'pk_test-123' });
document.body.append(widget);

React:

import { NexvioWidget } from '@nexvio-ai/widget-js/react';

export function SupportWidget() {
  return (
    <NexvioWidget
      options={{
        publicKey: 'pk_test-123',
        onEvent: (event) => console.log(event.name, event.detail),
      }}
      className="h-full w-full"
    />
  );
}

<nexvio-chat-bot> Options

The chatbot element extends all widget options and adds the following:

Chatbot-Specific Options

  • position ('bottom-right' | 'bottom-left' | 'top-right' | 'top-left') - Position of the chat button. Default: 'bottom-right'
  • defaultOpen (boolean) - Whether the widget should be open initially. Default: false
  • buttonColor (string) - Background color of the chat button. Default: '#3B82F6'
  • badge (number | boolean) - Show a notification badge. Pass a number for unread count, or true for a dot. Default: false
  • buttonIcon (string) - Custom SVG icon for the button (replaces default chat icon)
  • gap (number) - Gap from screen edge in pixels. Default: 20

Widget Options (Inherited)

All options from <nexvio-chat-widget> are supported:

  • publicKey (required) – widget identifier used by the Nexvio platform
  • appearance – overrides for colours, fonts, or density. Values are passed to the hosted widget frame
  • metadata / context – arbitrary JSON forwarded downstream
  • clientActions – map of callbacks that can be invoked by the iframe for client-side behaviour (e.g. analytics, navigation)
  • onEvent – receives all events emitted by the widget (ready, error, custom events defined in the workspace)
  • fetch – custom fetch implementation used when the frame requests server-side actions through the host
  • client.tools – client-side tools that can be called by the AI
  • startScreen – configuration for the initial greeting screen

Example: Full Configuration

const chatbot = document.createElement('nexvio-chat-bot');
chatbot.setOptions({
  publicKey: 'pk_test-123',
  position: 'bottom-right',
  buttonColor: '#6366F1',
  badge: 3, // Show unread count
  defaultOpen: false,
  gap: 24,
  appearance: {
    colorScheme: 'light',
  },
  context: {
    visitor: {
      name: 'John Doe',
      email: '[email protected]',
    },
  },
  onEvent: (event) => {
    console.log('Widget event:', event.name, event.detail);
  },
});
document.body.append(chatbot);

Programmatic Control

Methods

const chatbot = document.querySelector('nexvio-chat-bot');

// Open the widget
chatbot.open();

// Close the widget
chatbot.close();

// Toggle open/closed state
chatbot.toggle();

// Check if open
console.log(chatbot.isOpen); // boolean

// Access the underlying widget element
const widget = chatbot.widget;
widget?.focusInput();
widget?.setVisitor({ name: 'Jane Doe' });

Events

const chatbot = document.querySelector('nexvio-chat-bot');

// Listen to chatbot-specific events
chatbot.addEventListener('chatbot.opened', () => {
  console.log('Chat opened');
});

chatbot.addEventListener('chatbot.closed', () => {
  console.log('Chat closed');
});

// Listen to widget events (forwarded from the widget)
chatbot.addEventListener('nexvio.event', (event) => {
  console.log('Widget event:', event.detail);
});

React Usage

Basic Example

import { NexvioChatbot } from '@nexvio-ai/widget-js/react';
import { useRef } from 'react';

export function App() {
  const chatbotRef = useRef<NexvioChatbotElement>(null);

  return (
    <>
      <button onClick={() => chatbotRef.current?.open()}>
        Open Chat
      </button>

      <NexvioChatbot
        ref={chatbotRef}
        options={{
          publicKey: 'pk_test-123',
          buttonColor: '#6366F1',
          badge: 3,
        }}
      />
    </>
  );
}

With Event Handling

import { NexvioChatbot } from '@nexvio-ai/widget-js/react';
import type { NexvioWidgetEvent } from '@nexvio-ai/widget-js';

export function App() {
  const handleEvent = (event: NexvioWidgetEvent) => {
    console.log('Event:', event.name, event.detail);
  };

  return (
    <NexvioChatbot
      options={{
        publicKey: 'pk_test-123',
        onEvent: handleEvent,
        appearance: {
          colorScheme: 'dark',
        },
      }}
    />
  );
}

Using the Hook

import { useNexvioChatbot } from '@nexvio-ai/widget-js/react';
import { useEffect } from 'react';

export function App() {
  const { ref, setElement } = useNexvioChatbot({
    publicKey: 'pk_test-123',
    buttonColor: '#6366F1',
  });

  useEffect(() => {
    // Access the element via ref.current
    const chatbot = ref.current;
    if (chatbot) {
      chatbot.open();
    }
  }, []);

  return <nexvio-chat-bot ref={setElement} />;
}

<nexvio-chat-widget> Options

For direct widget usage, see the widget-specific options:

  • publicKey (required) – widget identifier used by the Nexvio platform
  • appearance – overrides for colours, fonts, or density. Values are passed to the hosted widget frame
  • metadata / context – arbitrary JSON forwarded downstream
  • clientActions – map of callbacks that can be invoked by the iframe for client-side behaviour (e.g. analytics, navigation)
  • onEvent – receives all events emitted by the widget (ready, error, custom events defined in the workspace)
  • fetch – custom fetch implementation used when the frame requests server-side actions through the host
  • messageActions – per-message UI action toggles (copy, feedback, retry)
  • client.tools – client-side tools that can be called by the AI
  • startScreen – configuration for the initial greeting screen

Styling

CSS Custom Properties

The chatbot element exposes CSS custom properties for styling:

nexvio-chat-bot {
  --chatbot-button-size: 60px;
  --chatbot-button-bg: #3B82F6;
  --chatbot-button-color: white;
  --chatbot-widget-width: 420px;
  --chatbot-widget-height: 600px;
  --chatbot-widget-gap: 20px;
}

Responsive Behavior

On mobile devices (screen width ≤ 768px), the widget automatically switches to full-screen mode for better usability.

Development

pnpm install
pnpm --filter @nexvio-ai/widget-js test
pnpm --filter @nexvio-ai/widget-js build

The build pipeline uses tsup to emit bundled ESM/CJS outputs with type declarations. Vitest covers the base utilities used to exchange data with the hosted iframe.

Demo Integration

The monorepo includes a live integration at apps/demo-app/src/app/widget/page.tsx. Launch it with:

pnpm --filter demo-app dev

The demo renders <NexvioWidget />, lets you swap the widget public key, and mirrors all bridge events in a side panel so you can validate host/widget communication in real time.

Migration Guide

From <nexvio-chat-widget> to <nexvio-chat-bot>

If you're currently using <nexvio-chat-widget> and want to switch to the chatbot:

Before:

const widget = document.createElement('nexvio-chat-widget');
widget.setOptions({ publicKey: 'pk_test-123' });
document.body.append(widget);

After:

const chatbot = document.createElement('nexvio-chat-bot');
chatbot.setOptions({ publicKey: 'pk_test-123' });
document.body.append(chatbot);

All widget options work the same way. The chatbot automatically creates and manages the widget internally.

TypeScript Support

Full TypeScript support is included:

import type {
  NexvioWidgetOptions,
  NexvioWidgetEvent,
  NexvioChatbotOptions,
} from '@nexvio-ai/widget-js';
import type { NexvioChatbotElement } from '@nexvio-ai/widget-js';

Browser Support

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • Mobile browsers (iOS Safari, Chrome Mobile)

Requires support for:

  • Custom Elements (Web Components)
  • Shadow DOM
  • ES2017+ features