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 can configure the mode, base URL, and other options:

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

const app = createApp(App)

app.use(SproutSidekick, {
  mode: 'PROD', // 'QA' or 'PROD' (default: 'QA')
  baseUrl: 'https://custom-backend.com', // Optional: custom URL (takes precedence over mode)
  skipDesignSystem: true,
})

app.mount('#app')

Configuration Options

Mode Option

The mode option determines which backend environment to use:

  • 'QA' or 'qa' (default): Connects to QA environment using VITE_CHAT_BE_QA
  • 'PROD' or 'prod': Connects to production environment using VITE_CHAT_BE_PROD

The mode is case-insensitive. If not specified, it defaults to 'QA'.

Base URL Option

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.

Priority Order:

  1. baseUrl (if provided) - highest priority
  2. mode (if provided) - uses corresponding environment variable
  3. Default to QA mode (VITE_CHAT_BE_QA)

Configuration Examples

Using mode only:

typescript
app.use(SproutSidekick, {
  mode: 'PROD', // Uses VITE_CHAT_BE_PROD
})

Using custom baseUrl:

typescript
app.use(SproutSidekick, {
  baseUrl: 'https://my-custom-backend.com', // Uses this URL directly
})

Using both (baseUrl takes precedence):

typescript
app.use(SproutSidekick, {
  mode: 'PROD',
  baseUrl: 'https://custom-backend.com', // This will be used, mode is ignored
})

Default (uses QA mode):

typescript
app.use(SproutSidekick) // Uses VITE_CHAT_BE_QA

Environment Variables

Make sure you have the corresponding environment variables set in your .env file:

env
VITE_CHAT_BE_QA=https://agent-center-be-qa.sprout.ph
VITE_CHAT_BE_PROD=https://agent-center-be.sprout.ph

Note: If you provide baseUrl in the plugin options, environment variables are not required for that specific configuration. However, they are still required if you use mode without providing baseUrl.

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_lbjocson/sprout-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_lbjocson/sprout-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_lbjocson/sprout-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_lbjocson/sprout-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.