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

@traiyani/chatsdk-vue

v1.1.5

Published

ChatSDK Vue.js SDK - Pre-built, plug-and-play real-time chat components for Vue 3

Readme

ChatSDK Vue.js SDK

Vue.js SDK for ChatSDK - Real-time chat solution with product-based conversations, Socket.IO, instant messaging, and file sharing. Fully isolated and self-contained.

Features

  • Zero boilerplate — 3 steps: install plugin, login, use <ChatPanel />
  • Fully isolated — all dependencies bundled, no global side effects, scoped CSS
  • Vue 3 Composition API
  • Real-time messaging via Socket.IO
  • Product-based conversations with metadata
  • File/image/video uploads and sharing
  • Block/unblock users
  • Internationalization (English + Arabic with RTL)
  • Dark mode support (light / dark / auto)
  • Typing indicators, read receipts, unread counts
  • CSS auto-injection — no manual stylesheet import required

Table of Contents

  1. Installation
  2. SDK Initialization (Plugin)
  3. User Authentication
  4. ChatPanel Component
  5. ChatPanel Props Reference
  6. Exposed Methods
  7. Theme Support
  8. Internationalization (i18n)
  9. TypeScript Support
  10. Troubleshooting

1. Installation

npm install @traiyani/chatsdk-vue

That's it. axios and socket.io-client are bundled inside the SDK — your website does not need to install them.

| Dependency | Minimum Version | |---|---| | vue | >= 3.0.0 |

Works with Vite, webpack, Laravel Mix, Nuxt 3, and any Vue 3 bundler out of the box.

CSS (Auto-Injected)

CSS is automatically injected when you import any SDK export. No manual stylesheet import is needed.

import { ChatPanel } from '@traiyani/chatsdk-vue';

All SDK styles are scoped under .chatsdk-root so they never conflict with your app's CSS (Bootstrap, Tailwind, etc.).

If you prefer to import the stylesheet manually (e.g., for SSR or custom loading order):

import '@traiyani/chatsdk-vue/dist/chatsdk.css';

Optional: Load Fonts

The SDK UI uses Mulish and Lato fonts. If your app doesn't already load them, add this to your HTML <head>:

<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@400;500;600;700&family=Lato:wght@400;700&display=swap" rel="stylesheet">

2. SDK Initialization

Register the SDK plugin once in your main.ts / main.js. This initializes the singleton SDK instance and makes it available to all components.

// main.ts
import { createApp } from 'vue';
import { ChatSDKPlugin } from '@traiyani/chatsdk-vue';
import App from './App.vue';

const app = createApp(App);

app.use(ChatSDKPlugin, {
  apiBaseUrl: 'https://your-chat-api.com/api',
  appId: 'your-app-id',
  environment: 'production',
});

app.mount('#app');

Configuration Options

| Option | Type | Required | Default | Description | |---|---|---|---|---| | apiBaseUrl | string | Yes | — | Chat API server URL | | appId | string | Yes | — | Your application ID | | environment | 'development' \| 'staging' \| 'production' | Yes | — | Environment | | enableLogging | boolean | No | false | Enable debug logging in console | | autoConnect | boolean | No | true | Auto-connect WebSocket after auth | | timeout | number | No | 30000 | HTTP request timeout in ms |

Environment Variables

Config values can come from any source:

// Vite
app.use(ChatSDKPlugin, {
  apiBaseUrl: import.meta.env.VITE_API_URL,
  appId: import.meta.env.VITE_APP_ID,
  environment: import.meta.env.VITE_ENVIRONMENT,
});

// Nuxt 3
const runtimeConfig = useRuntimeConfig();
app.use(ChatSDKPlugin, {
  apiBaseUrl: runtimeConfig.public.chatApiUrl,
  appId: runtimeConfig.public.chatAppId,
  environment: runtimeConfig.public.chatEnvironment,
});

3. User Authentication

Use the useChatSDK() composable to login, verify users, and logout. These are the only auth calls your website needs to make.

3.1 Login the Current User

Call login() once after the website user authenticates (e.g., after website login). This saves the chat token and connects the WebSocket.

import { useChatSDK } from '@traiyani/chatsdk-vue';

const { login } = useChatSDK();

// After your website login completes:
const chatUser = await login({
  id: 'user-external-id',    // Your app's user ID
  name: 'Ahmed',             // Display name
  email: '[email protected]', // Email
});

console.log('Chat user logged in:', chatUser.name);

What happens internally:

  1. Authenticates the user with the chat server (login or auto-register)
  2. Saves the auth token to localStorage
  3. Connects the WebSocket for real-time messaging

3.2 Verify Another User

Call verifyUser() to check if another user (e.g., a seller) exists in the chat system, or register them if they don't. This does NOT save a token or connect a socket — it's purely a lookup.

const { verifyUser } = useChatSDK();

const otherUser = await verifyUser({
  id: 'seller-456',
  name: 'Mohammed',
  email: '[email protected]',
});

console.log('Verified:', otherUser.name, otherUser.id);

3.3 Logout

Call logout() when the website user logs out. This disconnects the socket, clears the token, and cleans up all state.

const { logout } = useChatSDK();

await logout();

3.4 Reactive State

The composable exposes reactive state shared across all components:

const { currentUser, isInitialized, isConnected } = useChatSDK();

// In template:
// {{ currentUser?.name }}
// {{ isConnected ? 'Online' : 'Offline' }}

4. ChatPanel Component

<ChatPanel /> is the main UI component. It handles everything internally: conversation layout, socket rooms, real-time events, language switching, and error containment.

4.1 Open a Direct Chat (mode = "chat")

Opens a chat popup with a specific user, optionally about a product.

<template>
  <button @click="showChat = true">Chat with Seller</button>

  <ChatPanel
    v-model:visible="showChat"
    mode="chat"
    :target-user="{ id: product.ownerId }"
    :product="{
      productId: product.id,
      productName: product.name,
      productImage: product.image,
      price: product.price,
      currency: 'QAR',
      category: product.category,
    }"
    :chat-metadata="{ source: 'product-page', adType: 'featured' }"
    :external-group-id="myGroupId"
    :locale="currentLocale"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ChatPanel } from '@traiyani/chatsdk-vue';

const showChat = ref(false);
const currentLocale = ref('en');
const myGroupId = 'optional-custom-group-id';

const product = {
  id: 'CAR_123',
  ownerId: 'seller-456',
  name: 'Toyota Camry 2023',
  image: 'https://example.com/car.jpg',
  price: 25000,
  category: 'Vehicles',
};
</script>

4.2 Open Conversation List (mode = "conversations")

Opens a panel with the conversation list sidebar and chat window.

<template>
  <button @click="showConversations = true">
    My Messages
    <span v-if="unreadCount > 0">{{ unreadCount }}</span>
  </button>

  <ChatPanel
    ref="chatPanelRef"
    v-model:visible="showConversations"
    mode="conversations"
    :locale="currentLocale"
    :on-unread-count-change="(count) => unreadCount = count"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ChatPanel } from '@traiyani/chatsdk-vue';

const showConversations = ref(false);
const currentLocale = ref('en');
const unreadCount = ref(0);
const chatPanelRef = ref();
</script>

4.3 Chat with a User by Name + Email (No ID)

When you don't have the other user's external ID, pass their name and email. The SDK will authenticate/register them automatically.

<ChatPanel
  v-model:visible="showChat"
  mode="chat"
  :target-user="{ name: 'Ahmed', email: '[email protected]' }"
  :product="{ productId: '456', productName: 'Phone', productImage: 'https://...' }"
  :chat-metadata="{ source: 'user-profile' }"
  :locale="currentLocale"
/>

4.4 Target User Resolution Logic

| What you pass | SDK behavior | |---|---| | { id: 'ext-123' } | Uses ID directly, skips user verification | | { id: 'ext-123', name: 'Ahmed', email: '...' } | Uses ID directly, skips verification | | { name: 'Ahmed', email: '[email protected]' } | Authenticates/registers user by name + email, then uses returned ID | | { email: '[email protected]', phone: '+974...' } | Authenticates by email, phone stored as metadata |

Rule: If targetUser.id is present, the SDK skips verification. Otherwise, it authenticates the user first.

4.5 ExternalGroupId

The externalGroupId is a unique identifier for a conversation between two users (optionally about a product). It prevents duplicate conversations.

  • If you provide externalGroupId — the SDK uses it as-is.
  • If you omit it — the SDK generates one automatically using SHA-256 hash of the sorted user IDs + product ID.
<!-- SDK generates groupId automatically -->
<ChatPanel
  v-model:visible="showChat"
  mode="chat"
  :target-user="{ id: 'seller-456' }"
  :product="{ productId: 'CAR_123', productName: 'Car', productImage: '...' }"
/>

<!-- You provide your own groupId -->
<ChatPanel
  v-model:visible="showChat"
  mode="chat"
  :target-user="{ id: 'seller-456' }"
  :product="{ productId: 'CAR_123', productName: 'Car', productImage: '...' }"
  :external-group-id="myCustomGroupId"
/>

4.6 Complete Integration Example

Full working example — from install to running chat:

main.ts:

import { createApp } from 'vue';
import { ChatSDKPlugin } from '@traiyani/chatsdk-vue';
import App from './App.vue';

const app = createApp(App);

app.use(ChatSDKPlugin, {
  apiBaseUrl: import.meta.env.VITE_CHAT_API_URL,
  appId: import.meta.env.VITE_CHAT_APP_ID,
  environment: 'production',
});

app.mount('#app');

LoginPage.vue:

<script setup lang="ts">
import { useChatSDK } from '@traiyani/chatsdk-vue';

const { login } = useChatSDK();

async function handleWebsiteLogin(websiteUser) {
  // ... your website login logic ...

  // Then login to chat:
  await login({
    id: websiteUser.id,
    name: websiteUser.name,
    email: websiteUser.email,
  });
}
</script>

ProductPage.vue:

<template>
  <div class="product-page">
    <h1>{{ product.name }}</h1>
    <p>{{ product.price }} QAR</p>

    <button @click="showChat = true">Chat with Seller</button>

    <ChatPanel
      v-model:visible="showChat"
      mode="chat"
      :target-user="{ id: product.ownerId }"
      :product="{
        productId: product.id,
        productName: product.name,
        productImage: product.image,
        price: product.price,
        currency: 'QAR',
      }"
      :chat-metadata="{ source: 'product-page' }"
      :locale="currentLocale"
      :on-error="handleChatError"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ChatPanel } from '@traiyani/chatsdk-vue';

const showChat = ref(false);
const currentLocale = ref('en');

const product = {
  id: 'CAR_123',
  ownerId: 'seller-456',
  name: 'Toyota Camry 2023',
  image: 'https://example.com/car.jpg',
  price: 25000,
};

function handleChatError(error: Error) {
  console.error('Chat error:', error.message);
}
</script>

Navbar.vue (conversation list + unread badge):

<template>
  <nav>
    <button @click="showMessages = true">
      Messages
      <span v-if="unread > 0" class="badge">{{ unread }}</span>
    </button>

    <ChatPanel
      v-model:visible="showMessages"
      mode="conversations"
      :locale="currentLocale"
      :on-unread-count-change="(count) => unread = count"
    />

    <button @click="handleLogout">Logout</button>
  </nav>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ChatPanel, useChatSDK } from '@traiyani/chatsdk-vue';

const { logout } = useChatSDK();
const showMessages = ref(false);
const unread = ref(0);
const currentLocale = ref('en');

async function handleLogout() {
  await logout();
  // ... your website logout logic ...
}
</script>

5. ChatPanel Props Reference

| Prop | Type | Required | Default | Description | |---|---|---|---|---| | visible | boolean | Yes | — | Controls panel visibility. Use v-model:visible for two-way binding. | | mode | 'chat' \| 'conversations' | Yes | 'conversations' | 'chat' opens a direct chat popup. 'conversations' opens the conversation list with chat window. | | targetUser | TargetUser | For mode="chat" | — | The other party to chat with. See Target User Resolution. | | product | ProductContext | No | — | Product metadata to attach to the conversation. | | chatMetadata | Record<string, any> | No | — | Additional metadata for the chat (e.g., source, ad type). | | externalGroupId | string | No | — | Custom group ID. If omitted, the SDK generates one via SHA-256. | | locale | 'en' \| 'ar' | No | — | Language. Reactive — changing it switches the language automatically. | | onError | (error: Error) => void | No | — | Callback for errors. The panel catches all internal errors and calls this. | | onUnreadCountChange | (count: number) => void | No | — | Callback when unread conversation count changes (polled every 30s). |

TargetUser

interface TargetUser {
  id?: string;     // External user ID — if present, skip verification
  name?: string;   // Display name
  email?: string;  // Email
  phone?: string;  // Phone number (stored as metadata)
}

ProductContext

interface ProductContext {
  productId: string;
  productName: string;
  productImage?: string;
  price?: number;
  currency?: string;
  category?: string;
  productMetadata?: Record<string, any>;
}

6. Exposed Methods

Access methods on the <ChatPanel /> ref:

<template>
  <ChatPanel ref="chatPanelRef" ... />
</template>

<script setup>
import { ref } from 'vue';
const chatPanelRef = ref();

// Logout from chat (SDK + socket + clear tokens)
await chatPanelRef.value.logout();

// Get current unread conversations count
const count = await chatPanelRef.value.getUnreadCount();
</script>

| Method | Returns | Description | |---|---|---| | logout() | Promise<void> | Full cleanup: SDK logout + socket disconnect + clear tokens + close panel | | getUnreadCount() | Promise<number> | Returns the number of conversations with unread messages |


7. Theme Support

<script setup>
import { useTheme } from '@traiyani/chatsdk-vue';

const { theme, actualTheme, isDark, setTheme, toggleTheme } = useTheme();
</script>

<template>
  <div>
    <p>Current: {{ actualTheme }}</p>
    <button @click="toggleTheme">Toggle</button>
    <button @click="setTheme('dark')">Dark</button>
    <button @click="setTheme('light')">Light</button>
    <button @click="setTheme('auto')">Auto (system)</button>
  </div>
</template>

8. Internationalization (i18n)

Supported languages: English (en), Arabic (ar with RTL).

The <ChatPanel /> accepts a reactive locale prop and handles language switching internally. No manual calls needed.

<ChatPanel
  v-model:visible="showChat"
  mode="conversations"
  :locale="currentLocale"
/>

If you need direct access to i18n functions:

import { useI18n } from '@traiyani/chatsdk-vue';

const { t, changeLanguage, getCurrentLanguage, isRTL } = useI18n();

const title = t('conversations_title');
changeLanguage('ar');

9. TypeScript Support

Full type declarations are included. No extra @types/* packages needed.

import type {
  ChatSDKConfig,
  ChatSDKUser,
  ChatSDKMessage,
  ChatSDKConversation,
  ChatSDKLoginUser,
  ProductContext,
  TargetUser,
  Product,
  ChatState,
} from '@traiyani/chatsdk-vue';

10. Troubleshooting

| Problem | Solution | |---------|----------| | "SDK not initialized" | Ensure app.use(ChatSDKPlugin, config) is called in main.ts before mounting | | "No logged-in user" | Call useChatSDK().login() after your website login before opening ChatPanel | | WebSocket not connecting | Verify apiBaseUrl is correct and reachable, check CORS configuration | | CSS not applying | CSS is auto-injected on import. If missing, clear node_modules and reinstall | | Authentication fails | Verify apiBaseUrl and appId match your chat server configuration | | Panel not showing | Ensure v-model:visible is bound to a ref(true) value |

License

MIT