npm package: @mochii-ai/widget
Description: A customizable chat widget that can be easily integrated into any website or application
Latest version: 1.0.21

# @mochii-ai/widget

A powerful and customizable chat widget that can be easily integrated into your website or application. Supports multiple frameworks including vanilla JavaScript, React, and Vue.

## Installation

```bash
# Using npm
npm install @mochii-ai/widget

# Using yarn
yarn add @mochii-ai/widget

# Using pnpm
pnpm add @mochii-ai/widget
```

## Quick Start

### Script Tag

The simplest way to add the widget to your website is by adding the script tag:

```html
<!-- Add this before closing body tag -->
<script src="https://www.mochii.ai/widget.js"></script>
<script>
  new MochiiWidget({
    apiKey: "YOUR_API_KEY",
    domain: "https://www.mochii.ai",
    primaryColor: "#4CAF50",
    title: "Customer Support",
    firstMessages: [
      "👋 Hi! How can I help you today?",
      "Feel free to ask me anything!",
    ],
  });
</script>
```

For a more advanced configuration:

```html
<script src="https://www.mochii.ai/widget.js"></script>
<script>
  const widget = new MochiiWidget({
    apiKey: "YOUR_API_KEY",
    domain: "https://www.mochii.ai",
    primaryColor: "#4CAF50",
    title: "Customer Support",

    // Event callbacks
    callbacks: {
      onMessage: (message) => {
        console.log("New message:", message);
      },
    },

    // Page and user context
    contextProvider: {
      getPageContext: async () => ({
        url: window.location.href,
        title: document.title,
        description: document.querySelector('meta[name="description"]')
          ?.content,
      }),
      getUserContext: async () => ({
        userId: "user_123",
        preferences: {},
      }),
    },

    // Custom actions
    actions: [
      {
        name: "navigateTo",
        description: "Navigate to a specific page",
        parameters: {
          path: {
            type: "string",
            description: "The path to navigate to",
            required: true,
          },
        },
        execute: async ({ path }) => {
          window.location.href = path;
          return { success: true };
        },
      },
    ],

    firstMessages: [
      "👋 Hi! How can I help you today?",
      "Feel free to ask me anything!",
    ],
  });
</script>
```

### Module Import (Node.js/TypeScript)

```typescript
import { MochiiWidget } from "@mochii-ai/widget";

const initWidget = () => {
  const widget = new MochiiWidget({
    apiKey: process.env.MOCHII_API_KEY,
  });

  return widget;
};
```

### React

```tsx
import { memo } from "react";
import { MochiiChat } from "@mochii-ai/widget/react";

const ChatWidget = memo(() => {
  return <MochiiChat apiKey={process.env.NEXT_PUBLIC_MOCHII_API_KEY} />;
});

ChatWidget.displayName = "ChatWidget";

export default ChatWidget;
```

### Vue

```vue
<template>
  <MochiiChat :api-key="apiKey" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import { MochiiChat } from "@mochii-ai/widget/vue";

const apiKey = ref(import.meta.env.VITE_MOCHII_API_KEY);
</script>
```

## Configuration Options

### Basic Configuration

```typescript
const initWidget = () => {
  const widget = new MochiiWidget({
    // Required
    apiKey: process.env.MOCHII_API_KEY,

    // Optional appearance settings
    position: "bottom-right", // "bottom-right" | "bottom-left"
    theme: "auto", // "light" | "dark" | "auto"
    primaryColor: "#0070F3", // Primary brand color
    width: 380, // Width in pixels
    height: 600, // Height in pixels

    // Optional branding
    brandName: "Support Bot",
    inputPlaceholder: "Ask me anything...",
    avatar: "https://example.com/bot-avatar.png",

    // Optional messages
    firstMessages: [
      "Hello! How can I help you today?",
      "Feel free to ask any questions!",
    ],
    suggestedMessages: [
      "What are your business hours?",
      "How can I contact support?",
    ],

    // Optional contextual messages
    generateContextualMessages: {
      enabled: true,
      prompt: "Based on the current page context, generate a relevant greeting",
      generateSuggestions: true,
    },

    // Optional persistence
    persistChat: false,

    // Optional API configuration
    domain: "https://api.example.com",
  });

  return widget;
};
```

### Event Callbacks

```typescript
const initWidgetWithCallbacks = () => {
  const handleWidgetOpen = () => {
    console.log("Widget opened");
  };

  const handleWidgetClose = () => {
    console.log("Widget closed");
  };

  const handleNewMessage = (message: Message) => {
    console.log("New message received:", message);
  };

  const widget = new MochiiWidget({
    apiKey: process.env.MOCHII_API_KEY,
    callbacks: {
      onOpen: handleWidgetOpen,
      onClose: handleWidgetClose,
      onMessage: handleNewMessage,
    },
  });

  return widget;
};
```

### Context Providers

```typescript
interface PageContext {
  url: string;
  title: string;
  description?: string;
  language: string;
  currentRoute: string;
  customData: Record<string, unknown>;
}

interface UserContext {
  userId: string;
  preferences: {
    language: string;
    theme: string;
    notifications: boolean;
  };
  subscription: {
    plan: string;
    status: string;
  };
}

const initWidgetWithContext = () => {
  const getPageContext = async (): Promise<PageContext> => {
    return {
      url: window.location.href,
      title: document.title,
      description: document.querySelector('meta[name="description"]')?.content,
      language: document.documentElement.lang,
      currentRoute: window.location.pathname,
      customData: {
        category: "products",
        section: "electronics",
      },
    };
  };

  const getUserContext = async (): Promise<UserContext> => {
    return {
      userId: "user_123",
      preferences: {
        language: "en-US",
        theme: "dark",
        notifications: true,
      },
      subscription: {
        plan: "premium",
        status: "active",
      },
    };
  };

  const widget = new MochiiWidget({
    apiKey: process.env.MOCHII_API_KEY,
    contextProvider: {
      getPageContext,
      getUserContext,
    },
  });

  return widget;
};
```

### Custom Actions

```typescript
interface SearchProductsParams {
  query: string;
  category?: string;
}

interface SearchProductsResult {
  success: boolean;
  data?: unknown;
  error?: string;
}

const initWidgetWithActions = () => {
  const searchProducts = async ({
    query,
    category,
  }: SearchProductsParams): Promise<SearchProductsResult> => {
    try {
      const results = await searchProductsAPI(query, category);
      return {
        success: true,
        data: results,
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : "Unknown error",
      };
    }
  };

  const widget = new MochiiWidget({
    apiKey: process.env.MOCHII_API_KEY,
    actions: [
      {
        name: "searchProducts",
        description: "Search for products in the catalog",
        parameters: {
          query: {
            type: "string",
            description: "Search query",
            required: true,
          },
          category: {
            type: "string",
            description: "Product category",
            required: false,
          },
        },
        execute: searchProducts,
      },
    ],
  });

  return widget;
};
```

## Types

### Message Interface

```typescript
interface Message {
  role: "user" | "assistant"; // Message sender
  content: string; // Message content
  timestamp: number; // Unix timestamp
}
```

## Browser Support

The widget supports all modern browsers:

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)

## Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

## License

MIT License - see the [LICENSE](LICENSE) file for details.