> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deploystack.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Global Sonner Toast System

> Developer guide for using the global Sonner toast notification system in the DeployStack frontend.

DeployStack uses [Sonner](https://sonner.emilkowal.ski/) for toast notifications, providing elegant and accessible notifications across the entire application. The system is globally configured and requires no additional setup in individual components.

## Architecture Overview

The global Sonner toaster is configured in `App.vue` as the root-level toast provider:

```vue theme={null}
<!-- App.vue -->
<template>
  <div class="min-h-screen bg-gray-50">
    <RouterView />
    <Toaster class="pointer-events-auto" />
  </div>
</template>

<script setup lang="ts">
import { Toaster } from '@/components/ui/sonner'
import 'vue-sonner/style.css'
</script>
```

This setup ensures toasts are displayed consistently across all routes and components without requiring local toast providers.

## Basic Usage

### Importing and Using Toasts

```vue theme={null}
<script setup lang="ts">
import { toast } from 'vue-sonner'

// Success toast
const handleSuccess = () => {
  toast.success('Operation completed successfully!')
}

// Error toast
const handleError = () => {
  toast.error('Something went wrong')
}

// Warning toast
const handleWarning = () => {
  toast.warning('Please review your changes')
}

// Info toast
const handleInfo = () => {
  toast('Information message')
}
</script>
```

### Toast with Description

```typescript theme={null}
toast.success('Team updated successfully!', {
  description: 'Your team settings have been saved.'
})

toast.error('Failed to save team', {
  description: 'Network connection error. Please try again.'
})
```

## Real-World Examples

### API Success/Error Handling

```vue theme={null}
<script setup lang="ts">
import { toast } from 'vue-sonner'
import { TeamService } from '@/services/teamService'

const saveTeam = async () => {
  try {
    const updatedTeam = await TeamService.updateTeam(teamId, updateData)
    
    // Success toast with description
    toast.success(t('teams.manage.saveSuccess'), {
      description: t('teams.manage.saveSuccessDescription')
    })
    
    return updatedTeam
  } catch (error) {
    // Error toast with error details
    toast.error(t('teams.manage.saveError'), {
      description: error.message
    })
    throw error
  }
}
</script>
```

### Form Validation Feedback

```vue theme={null}
<script setup lang="ts">
import { toast } from 'vue-sonner'

const validateForm = () => {
  if (!formData.name.trim()) {
    toast.error('Validation Error', {
      description: 'Team name is required'
    })
    return false
  }
  
  if (formData.name.length > 100) {
    toast.warning('Name too long', {
      description: 'Team name must be 100 characters or less'
    })
    return false
  }
  
  return true
}
</script>
```

### Async Operations with Loading States

```vue theme={null}
<script setup lang="ts">
import { toast } from 'vue-sonner'

const deployServer = async () => {
  // Show loading toast
  const loadingToast = toast.loading('Deploying server...', {
    description: 'This may take a few minutes'
  })
  
  try {
    await McpServerService.deploy(serverId)
    
    // Dismiss loading toast and show success
    toast.dismiss(loadingToast)
    toast.success('Server deployed successfully!', {
      description: `Server ${serverName} is now running`
    })
  } catch (error) {
    // Dismiss loading toast and show error
    toast.dismiss(loadingToast)
    toast.error('Deployment failed', {
      description: error.message
    })
  }
}
</script>
```

## Advanced Usage

### Custom Duration

```typescript theme={null}
// Auto-dismiss after 10 seconds
toast.success('Long message', {
  duration: 10000
})

// Persistent toast (requires manual dismiss)
toast.error('Critical error', {
  duration: Infinity
})
```

### Action Buttons

```typescript theme={null}
toast('New version available', {
  description: 'Click to update your application',
  action: {
    label: 'Update',
    onClick: () => updateApplication()
  }
})
```

### Custom Styling

```typescript theme={null}
toast.success('Custom styled toast', {
  className: 'custom-toast',
  style: {
    background: 'linear-gradient(45deg, #ff6b6b, #4ecdc4)'
  }
})
```

## Integration with Internationalization

Combine Sonner with the [i18n system](/development/frontend/internationalization) for localized messages:

```vue theme={null}
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { toast } from 'vue-sonner'

const { t } = useI18n()

const saveSettings = async () => {
  try {
    await SettingsService.save(settings)
    
    toast.success(t('settings.saveSuccess'), {
      description: t('settings.saveSuccessDescription')
    })
  } catch (error) {
    toast.error(t('settings.saveError'), {
      description: t('settings.errorMessages.networkError')
    })
  }
}
</script>
```

## Event Bus Integration

Sonner works seamlessly with the [global event bus](/development/frontend/event-bus):

```vue theme={null}
<script setup lang="ts">
import { useEventBus } from '@/composables/useEventBus'
import { toast } from 'vue-sonner'

const eventBus = useEventBus()

// Listen for global notification events
eventBus.on('notification-show', (data) => {
  switch (data.type) {
    case 'success':
      toast.success(data.message)
      break
    case 'error':
      toast.error(data.message)
      break
    case 'warning':
      toast.warning(data.message)
      break
    default:
      toast(data.message)
  }
})

// Emit notifications from other components
const triggerGlobalNotification = () => {
  eventBus.emit('notification-show', {
    message: 'Global notification',
    type: 'success'
  })
}
</script>
```

## Best Practices

### 1. Use Appropriate Toast Types

```typescript theme={null}
// Good: Use semantic types
toast.success('Data saved')     // For successful operations
toast.error('Save failed')      // For errors and failures
toast.warning('Unsaved changes') // For warnings and cautions
toast('Information')            // For neutral information

// Avoid: Using wrong types
toast.success('Error occurred')  // Wrong type for error
toast.error('Success message')   // Confusing for users
```

### 2. Provide Meaningful Descriptions

```typescript theme={null}
// Good: Clear and actionable
toast.error('Failed to save team', {
  description: 'Network connection error. Please check your internet connection and try again.'
})

// Avoid: Vague messages
toast.error('Error', {
  description: 'Something went wrong'
})
```

### 3. Handle Loading States

```vue theme={null}
<script setup lang="ts">
const handleAsyncOperation = async () => {
  const loadingToast = toast.loading('Processing...')
  
  try {
    await performOperation()
    toast.dismiss(loadingToast)
    toast.success('Operation completed')
  } catch (error) {
    toast.dismiss(loadingToast)
    toast.error('Operation failed')
  }
}
</script>
```

### 4. Avoid Toast Spam

```typescript theme={null}
// Good: Debounce frequent operations
import { debounce } from 'lodash-es'

const debouncedSave = debounce(() => {
  toast.success('Auto-saved')
}, 1000)

// Avoid: Toast on every input change
const handleInput = () => {
  toast('Input changed') // Too frequent!
}
```

## Common Pitfalls

### ❌ Don't Add Multiple Toasters

```vue theme={null}
<!-- DON'T: Never add local Toaster components -->
<template>
  <div>
    <Toaster /> <!-- This will create duplicate toasts -->
    <!-- component content -->
  </div>
</template>
```

The global Toaster in `App.vue` handles all notifications automatically.

### ❌ Don't Overuse Toasts

```typescript theme={null}
// DON'T: Toast for every minor action
toast('Button clicked')
toast('Mouse moved')
toast('Form field focused')

// DO: Toast for meaningful user feedback
toast.success('Settings saved')
toast.error('Login failed')
toast.warning('Session expiring soon')
```

### ❌ Don't Forget Error Handling

```typescript theme={null}
// DON'T: Silent failures
const saveData = async () => {
  try {
    await api.save(data)
    toast.success('Saved!')
  } catch (error) {
    // Silent failure - user doesn't know what happened
  }
}

// DO: Always provide error feedback
const saveData = async () => {
  try {
    await api.save(data)
    toast.success('Data saved successfully')
  } catch (error) {
    toast.error('Failed to save data', {
      description: error.message
    })
  }
}
```

## Testing Toasts

### Unit Testing

```typescript theme={null}
// tests/components/TeamManager.test.ts
import { vi } from 'vitest'
import { toast } from 'vue-sonner'

// Mock toast functions
vi.mock('vue-sonner', () => ({
  toast: {
    success: vi.fn(),
    error: vi.fn(),
    warning: vi.fn(),
  }
}))

describe('TeamManager', () => {
  it('shows success toast when team is saved', async () => {
    const wrapper = mount(TeamManager)
    
    await wrapper.vm.saveTeam()
    
    expect(toast.success).toHaveBeenCalledWith(
      'Team updated successfully!',
      { description: 'Your team settings have been saved.' }
    )
  })
})
```

## Migration from Other Toast Systems

### From Vue-Toastification

```typescript theme={null}
// Before (vue-toastification)
this.$toast.success('Success message')
this.$toast.error('Error message')

// After (Sonner)
import { toast } from 'vue-sonner'
toast.success('Success message')
toast.error('Error message')
```

### From Custom Alert Components

```vue theme={null}
<!-- Before: Custom Alert components -->
<Alert v-if="showSuccess" variant="success">
  <AlertDescription>Success message</AlertDescription>
</Alert>

<Alert v-if="showError" variant="destructive">
  <AlertDescription>Error message</AlertDescription>
</Alert>
```

```vue theme={null}
<!-- After: Sonner toasts -->
<script setup lang="ts">
import { toast } from 'vue-sonner'

const handleSuccess = () => {
  toast.success('Success message')
}

const handleError = () => {
  toast.error('Error message')
}
</script>
```

The global Sonner system provides a consistent, accessible, and developer-friendly way to handle notifications across the entire DeployStack application.
