Skip to content

Usage Guide

Basic Usage

After installation, you can use the chat components in your Vue templates.

SidekickChat Component

The SidekickChat component provides a full chat interface suitable for main content areas:

vue
<template>
  <div class="container mx-auto p-4">
    <div class="h-96">
      <SidekickChat />
    </div>
  </div>
</template>

SidekickChatPlugin Component

The SidekickChatPlugin component provides a floating chat widget:

vue
<template>
  <div>
    <!-- Your main content -->
    <main>
      <h1>Welcome to our website</h1>
      <p>Your content here...</p>
    </main>

    <!-- Floating chat widget -->
    <SidekickChatPlugin
      @open="handleChatOpen"
      @close="handleChatClose"
      @toggle="handleChatToggle"
    />
  </div>
</template>

<script setup lang="ts">
function handleChatOpen() {
  console.log('Chat widget opened')
}

function handleChatClose() {
  console.log('Chat widget closed')
}

function handleChatToggle(isOpen: boolean) {
  console.log('Chat widget toggled:', isOpen)
}
</script>

Configuration

When installing the plugin, you must configure the required parameters and can optionally set additional options:

typescript
import { createApp } from 'vue'
import SproutSidekick from '@sprout_ai_labs/sidekick'
import '@sprout_ai_labs/sidekick/dist/sprout-sidekick.css'
import App from './App.vue'

const app = createApp(App)

app.use(SproutSidekick, {
  mode: 'PROD', // Required: 'QA' or 'PROD'
  appName: 'My Application', // Required: Your application name (used for analytics)
  baseUrl: 'https://custom-backend.com', // Optional: custom URL (takes precedence over mode)
  deviceSource: 'web', // Optional: 'web' or 'mobile' (default: 'web')
  skipDesignSystem: true, // Optional
})

app.mount('#app')

Configuration Options

Required Parameters

Mode (mode)

Required - Determines which backend environment to use.

  • Type: 'QA' | 'PROD' | 'qa' | 'prod'
  • Required: Yes
  • Case-insensitive
  • 'QA' or 'qa': Connects to QA environment using VITE_CHAT_BE_QA
  • 'PROD' or 'prod': Connects to production environment using VITE_CHAT_BE_PROD
App Name (appName)

Required - Identifies your application in analytics.

  • Type: string
  • Required: Yes
  • Purpose: All analytics events will include this app name for tracking and segmentation
  • Example: 'Sprout HR', 'Sprout Payroll', 'Mobile App'

Optional Parameters

Base URL (baseUrl)

The baseUrl option allows you to specify a custom backend URL directly. If baseUrl is provided, it takes precedence over mode and will be used regardless of the mode setting.

  • Type: string
  • Required: No
Device Source (deviceSource)
  • Type: 'mobile' | 'web'
  • Required: No
  • Default: 'web'

Priority Order for Backend URL:

  1. baseUrl (if provided) - highest priority
  2. mode (uses corresponding environment variable)
  3. Error if neither is configured properly

Configuration Examples

Minimal configuration (QA environment):

typescript
app.use(SproutSidekick, {
  mode: 'QA', // Required
  appName: 'Sprout HR', // Required
})

Production configuration:

typescript
app.use(SproutSidekick, {
  mode: 'PROD', // Required
  appName: 'Sprout Payroll', // Required
})

Mobile app configuration:

typescript
app.use(SproutSidekick, {
  mode: 'PROD', // Required
  appName: 'Sprout Mobile', // Required
  deviceSource: 'mobile', // Optional: Specify device type
})

Using custom baseUrl (overrides mode):

typescript
app.use(SproutSidekick, {
  mode: 'QA', // Required (even though baseUrl will be used)
  appName: 'Custom App', // Required
  baseUrl: 'https://my-custom-backend.com', // This URL will be used
})

Authentication

Both components require authentication before users can send messages. You can set up authentication programmatically:

vue
<script setup lang="ts">
import { useChatStore } from '@sprout_ai_labs/sidekick'
import { onMounted } from 'vue'

const chatStore = useChatStore()

onMounted(async () => {
  // Example: Get token from your authentication system
  const token = await getAuthToken()
  chatStore.setToken(token)
})

async function getAuthToken() {
  // Your authentication logic here
  const response = await fetch('/api/auth/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      userId: 'current-user-id',
    }),
  })

  const data = await response.json()
  return data.token
}
</script>

Shared State

Both components automatically share the same chat state. Messages sent in one component will appear in the other:

vue
<template>
  <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
    <!-- Left: Full chat interface -->
    <div class="h-96">
      <SidekickChat />
    </div>

    <!-- Right: State information -->
    <div class="p-4 bg-gray-100 rounded">
      <h3 class="font-bold mb-2">Chat State</h3>
      <p>Messages: {{ messageCount }}</p>
      <p>Connected: {{ isConnected }}</p>
      <p>Authenticated: {{ isAuthenticated }}</p>
    </div>
  </div>

  <!-- Floating widget shares the same state -->
  <SidekickChatPlugin />
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useChatStore } from '@sprout_ai_labs/sidekick'

const chatStore = useChatStore()

const messageCount = computed(() => chatStore.messageCount)
const isConnected = computed(() => chatStore.isConnected)
const isAuthenticated = computed(() => chatStore.isAuthenticated)
</script>

Chat Store Actions

You can interact with the chat store directly:

typescript
import { useChatStore } from '@sprout_ai_labs/sidekick'

const chatStore = useChatStore()

// Authentication
chatStore.setToken('your-token')
chatStore.clearToken()

// Messages
chatStore.addMessage('Hello!', 'user')
chatStore.addMessage('Hi there!', 'bot')
chatStore.clearMessages()

// Chat state
chatStore.openChat()
chatStore.closeChat()
chatStore.toggleChat()

// Send a message (includes bot response simulation)
await chatStore.sendMessage('How can I help you?')

Event Handling

The SidekickChatPlugin component emits events for open/close actions:

vue
<template>
  <SidekickChatPlugin @open="onOpen" @close="onClose" @toggle="onToggle" />
</template>

<script setup lang="ts">
function onOpen() {
  // Chat widget was opened
  console.log('Chat opened')

  // Example: Track analytics
  analytics.track('chat_opened')
}

function onClose() {
  // Chat widget was closed
  console.log('Chat closed')

  // Example: Save draft message
  saveDraftMessage()
}

function onToggle(isOpen: boolean) {
  // Chat widget was toggled
  console.log(`Chat is now ${isOpen ? 'open' : 'closed'}`)
}
</script>

Styling and Customization

The components can be customized by overriding CSS variables or classes:

css
/* Custom styling */
.sidekick-chat {
  --primary-color: #10b981;
  --background-color: #f9fafb;
}

.sidekick-chat-plugin {
  /* Custom positioning */
  bottom: 2rem;
  right: 2rem;
}

/* Custom message bubble styling */
.sidekick-chat .message-user {
  background-color: #10b981;
}

Error Handling

Handle authentication and message sending errors:

vue
<script setup lang="ts">
import { useChatStore } from '@sprout_ai_labs/sidekick'
import { ref } from 'vue'

const chatStore = useChatStore()
const error = ref<string | null>(null)

async function sendMessage(text: string) {
  try {
    error.value = null
    await chatStore.sendMessage(text)
  } catch (err) {
    error.value = err instanceof Error ? err.message : 'Failed to send message'
    console.error('Chat error:', err)
  }
}
</script>

<template>
  <div>
    <div v-if="error" class="p-3 bg-red-100 text-red-700 rounded mb-4">
      {{ error }}
    </div>
    <SidekickChat />
  </div>
</template>

Best Practices

  1. Authentication: Always set up proper authentication before allowing users to chat
  2. Error Handling: Implement proper error handling for network failures
  3. Accessibility: Ensure proper focus management and keyboard navigation
  4. Performance: Consider implementing message pagination for large chat histories
  5. Security: Validate and sanitize all user inputs on the server side

Next Steps

Learn more about the component APIs in the API Reference.

Released under the MIT License.