Zum Inhalt springen

React-Integrationsleitfaden

Dieser Leitfaden behandelt Muster zur Integration des Univerx Client SDK in React-Anwendungen, einschließlich eines wiederverwendbaren benutzerdefinierten Hooks und Next.js-spezifischen Überlegungen.

Erstellen Sie die SDK-Instanz innerhalb von useEffect, damit sie nur im Browser ausgeführt wird. Rufen Sie immer widget.destroy() in der Cleanup-Funktion auf, um Speicherlecks und veraltete Verbindungen zu vermeiden.

import { WidgetClient } from "@univerx/client-sdk";
import { useEffect, useRef } from "react";
export function SupportWidget() {
const widgetRef = useRef<WidgetClient | null>(null);
useEffect(() => {
const widget = new WidgetClient({
widgetKey: "your-widget-key",
onAgentAssigned: (agent) => console.log(`Agent: ${agent.name}`),
onCallEnded: () => widgetRef.current?.destroy(),
});
widget.init();
widgetRef.current = widget;
return () => {
widgetRef.current?.destroy();
};
}, []);
// The SDK renders its own UI — this component is a lifecycle wrapper
return null;
}

Extrahieren Sie die Widget-Logik in einen wiederverwendbaren Hook, um Komponenten sauber zu halten und den Widget-Status für Ihre UI verfügbar zu machen:

import { WidgetClient, WidgetConfig, WidgetState } from "@univerx/client-sdk";
import { useEffect, useRef, useState } from "react";
export function useWidget(config: WidgetConfig) {
const widgetRef = useRef<WidgetClient | null>(null);
const [state, setState] = useState<WidgetState>("idle");
const [queuePosition, setQueuePosition] = useState<number | null>(null);
useEffect(() => {
const widget = new WidgetClient({
...config,
onReady: () => setState("ready"),
onCallStarted: () => setState("in_call"),
onCallEnded: () => setState("ended"),
});
widget.on("queue:update", (position) => setQueuePosition(position));
widget.on("queue:left", () => setQueuePosition(null));
widget.init();
widgetRef.current = widget;
return () => {
widget.destroy();
widgetRef.current = null;
};
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return {
widget: widgetRef.current,
state,
queuePosition,
};
}

Verwendung in einer Komponente:

export function SupportButton() {
const { widget, state, queuePosition } = useWidget({
widgetKey: "your-widget-key",
});
const handleClick = async () => {
if (state === "ready") {
await widget?.joinQueue({ terms: true });
}
};
return (
<button onClick={handleClick} disabled={state !== "ready"}>
{state === "queued" ? `Position ${queuePosition}` : "Get support"}
</button>
);
}

Wenn ein Agent Cobrowsing anfordert, emittiert das SDK cobrowse:consent:required mit Handler-Funktionen. Rendern Sie Ihre eigene Zustimmungs-UI und rufen Sie den entsprechenden Handler auf:

useEffect(() => {
const widget = new WidgetClient({ widgetKey: "your-widget-key" });
widget.on("cobrowse:consent:required", ({ accept, decline }) => {
// Show your consent modal, then call accept() or decline()
setConsentHandlers({ accept, decline });
setShowConsentModal(true);
});
widget.init();
widgetRef.current = widget;
return () => widget.destroy();
}, []);

Fügen Sie "use client" oben in jeder Datei hinzu, die das SDK importiert oder instanziiert:

"use client";
import { WidgetClient } from "@univerx/client-sdk";

In Next.js müssen Umgebungsvariablen, auf die auf dem Client zugegriffen wird, das Präfix NEXT_PUBLIC_ verwenden:

Terminal-Fenster
NEXT_PUBLIC_UNIVERX_WIDGET_KEY=your-widget-key-here
const widget = new WidgetClient({
widgetKey: process.env.NEXT_PUBLIC_UNIVERX_WIDGET_KEY!,
});

Um das Widget auf jeder Seite zu rendern, fügen Sie es zu Ihrem Root-Layout hinzu. Da SupportWidget eine Client-Komponente ist, kann das Layout selbst eine Server-Komponente bleiben:

app/layout.tsx
import { SupportWidget } from "@/components/SupportWidget";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
{children}
<SupportWidget />
</body>
</html>
);
}

Für den Pages Router fügen Sie das Widget zu _app.tsx hinzu:

pages/_app.tsx
import type { AppProps } from "next/app";
import { SupportWidget } from "@/components/SupportWidget";
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<SupportWidget />
</>
);
}