Svelte-Integrationsleitfaden
Dieser Leitfaden behandelt Muster zur Integration des Univerx Client SDK in Svelte-Anwendungen, einschließlich reaktivem Status mit Svelte Stores und SvelteKit SSR-Überlegungen.
Grundlegende Integration
Abschnitt betitelt „Grundlegende Integration“Verwenden Sie onMount, um das Widget zu initialisieren, und onDestroy, um aufzuräumen. Beide Lifecycle-Funktionen werden garantiert nur im Browser ausgeführt.
<script lang="ts"> import { onMount, onDestroy } from 'svelte'; import { WidgetClient } from '@univerx/client-sdk';
let widget: WidgetClient | null = null;
onMount(() => { widget = new WidgetClient({ widgetKey: 'your-widget-key', onAgentAssigned: (agent) => console.log(`Agent: ${agent.name}`), onCallEnded: () => widget?.destroy(), });
widget.init(); });
onDestroy(() => { widget?.destroy(); widget = null; });</script>
<!-- SDK renders its own UI; no markup needed -->Reaktiver Status mit Svelte Stores
Abschnitt betitelt „Reaktiver Status mit Svelte Stores“Verwenden Sie Sveltes eingebaute writable Stores, um den Widget-Status für Ihr Template und andere Komponenten verfügbar zu machen:
<script lang="ts"> import { onMount, onDestroy } from 'svelte'; import { writable } from 'svelte/store'; import { WidgetClient } from '@univerx/client-sdk'; import type { WidgetState, Agent } from '@univerx/client-sdk';
const state = writable<WidgetState>('idle'); const queuePosition = writable<number | null>(null); const currentAgent = writable<Agent | null>(null);
let widget: WidgetClient | null = null;
onMount(() => { widget = new WidgetClient({ widgetKey: 'your-widget-key', onReady: () => state.set('ready'), onCallStarted: () => state.set('in_call'), onCallEnded: () => state.set('ended'), });
widget.on('queue:update', (pos) => queuePosition.set(pos)); widget.on('queue:left', () => queuePosition.set(null)); widget.on('agent:assigned', (agent) => currentAgent.set(agent));
widget.init(); });
onDestroy(() => { widget?.destroy(); widget = null; });
async function joinQueue() { await widget?.joinQueue({ terms: true }); state.set('queued'); }
async function endCall() { await widget?.endSession(); }</script>
{#if $state === 'ready'} <button on:click={joinQueue}>Get support</button>{/if}
{#if $state === 'queued'} <p>Queue position: {$queuePosition}</p>{/if}
{#if $state === 'in_call'} <button on:click={endCall}>End call</button>{/if}Gemeinsames Store-Modul
Abschnitt betitelt „Gemeinsames Store-Modul“Um die Widget-Instanz über mehrere Komponenten hinweg zu teilen, exportieren Sie einen Store und eine init-Funktion aus einem dedizierten Modul:
import { writable, get } from 'svelte/store';import { WidgetClient } from '@univerx/client-sdk';import type { WidgetConfig, WidgetState, Agent } from '@univerx/client-sdk';
export const widgetState = writable<WidgetState>('idle');export const queuePosition = writable<number | null>(null);export const currentAgent = writable<Agent | null>(null);
let instance: WidgetClient | null = null;
export function initWidget(config: WidgetConfig): void { if (instance) return; // already initialised
instance = new WidgetClient({ ...config, onReady: () => widgetState.set('ready'), onCallStarted: () => widgetState.set('in_call'), onCallEnded: () => widgetState.set('ended'), });
instance.on('queue:update', (pos) => queuePosition.set(pos)); instance.on('queue:left', () => queuePosition.set(null)); instance.on('agent:assigned', (agent) => currentAgent.set(agent));
instance.init();}
export function destroyWidget(): void { instance?.destroy(); instance = null;}
export function getWidget(): WidgetClient | null { return instance;}Verwenden Sie es in Ihrer Root-Layout-Komponente:
<script lang="ts"> import { onMount, onDestroy } from 'svelte'; import { initWidget, destroyWidget } from '$lib/widget';
onMount(() => { initWidget({ widgetKey: 'your-widget-key' }); });
onDestroy(() => { destroyWidget(); });</script>
<slot />Cobrowsing-Zustimmung
Abschnitt betitelt „Cobrowsing-Zustimmung“Lauschen Sie auf cobrowse:consent:required und binden Sie die Handler an lokalen Status, um Ihre Zustimmungs-UI zu steuern:
<script lang="ts"> import { onMount, onDestroy } from 'svelte'; import { WidgetClient } from '@univerx/client-sdk';
let widget: WidgetClient | null = null; let consentHandlers: { accept: () => void; decline: () => void } | null = null;
onMount(() => { widget = new WidgetClient({ widgetKey: 'your-widget-key' });
widget.on('cobrowse:consent:required', (handlers) => { consentHandlers = handlers; });
widget.init(); });
onDestroy(() => { widget?.destroy(); });</script>
{#if consentHandlers} <div class="consent-dialog"> <p>The agent is requesting screen access. Do you allow cobrowsing?</p> <button on:click={() => { consentHandlers?.accept(); consentHandlers = null; }}> Allow </button> <button on:click={() => { consentHandlers?.decline(); consentHandlers = null; }}> Decline </button> </div>{/if}SvelteKit SSR
Abschnitt betitelt „SvelteKit SSR“SvelteKit rendert Seiten standardmäßig auf dem Server. Da onMount nur im Browser ausgeführt wird, ist die Initialisierung darin bereits sicher. Wenn Sie jedoch auf Modul-Ebene in einer +page.server.ts oder in reinem Server-Code auf das SDK verweisen, wird ein Fehler ausgelöst.
Für dynamische Imports in Randfällen:
<script lang="ts"> import { onMount } from 'svelte'; import type { WidgetClient } from '@univerx/client-sdk';
let widget: WidgetClient | null = null;
onMount(async () => { // Dynamically import to ensure the module is never evaluated on the server const { WidgetClient } = await import('@univerx/client-sdk'); widget = new WidgetClient({ widgetKey: 'your-widget-key' }); widget.init(); });</script>