Documentation d'intégration
Installez SupportDesk dans votre application en moins de 5 minutes.
Vue d'ensemble
SupportDesk est un widget embarquable qui ajoute un assistant support complet à votre application : IA pour répondre aux questions, tickets, base de connaissances, feedback.
Il fonctionne en deux parties :
- Le script CDN — un fichier JS unique (~100 KB gzippé) à charger sur votre site
- L'API
window.SupportDesk— pour contrôler le widget (ouvrir, fermer, transmettre l'utilisateur connecté)
Le widget est isolé dans un Shadow DOM : ses styles n'interfèrent pas
avec les vôtres. Il s'adapte à votre thème via l'option primaryColor.
1. Créer un compte
- Rendez-vous sur supportdesk.innovartx.com/admin/signup
- Remplissez le formulaire (nom de l'entreprise, slug, email admin, mot de passe)
-
Copiez les identifiants affichés sur l'écran de confirmation — ils ne seront plus
visibles ensuite :
- App ID — identifiant de votre espace
- Public Key — pour le widget (
pk_live_...) - API Key — pour les appels serveur (
sk_live_...) - Webhook Secret — pour signer les webhooks
2. Intégration React
Créez un provider qui charge le widget une fois l'utilisateur connecté. Le script est chargé dynamiquement côté client, donc compatible avec Next.js, Remix, React Router v7 et toute config SSR.
Variables d'environnement
Dans votre .env :
VITE_SUPPORTDESK_APP_ID=votre-app-id
VITE_SUPPORTDESK_PUBLIC_KEY=pk_live_xxxxxxxxxxxx
VITE_SUPPORTDESK_WIDGET_URL=https://supportdesk-widget.vercel.app/v1/supportdesk-widget.js Le provider
// src/providers/SupportDeskProvider.tsx
import { useEffect, useRef } from 'react';
import { useAuth } from '@/hooks/useAuth'; // votre hook d'auth
declare global {
interface Window {
SupportDesk?: {
init: (config: any) => void;
destroy: () => void;
open: () => void;
close: () => void;
toggle: () => void;
isOpen: () => boolean;
onUnreadChange: (cb: (n: number) => void) => () => void;
};
}
}
const WIDGET_URL = import.meta.env.VITE_SUPPORTDESK_WIDGET_URL;
const APP_ID = import.meta.env.VITE_SUPPORTDESK_APP_ID;
const PUBLIC_KEY = import.meta.env.VITE_SUPPORTDESK_PUBLIC_KEY;
export function SupportDeskProvider({ children }: { children: React.ReactNode }) {
const { user } = useAuth();
const scriptLoadedRef = useRef(false);
const currentUserIdRef = useRef<string | null>(null);
useEffect(() => {
if (!user || !WIDGET_URL) return;
const init = () => {
window.SupportDesk?.destroy();
window.SupportDesk?.init({
appId: APP_ID,
apiKey: PUBLIC_KEY,
customer: {
externalId: user.id,
email: user.email,
name: user.name,
},
theme: { primaryColor: '#2563eb', showButton: false },
});
currentUserIdRef.current = user.id;
};
if (scriptLoadedRef.current && window.SupportDesk) {
if (currentUserIdRef.current !== user.id) init();
return;
}
const script = document.createElement('script');
script.src = WIDGET_URL;
script.async = true;
script.onload = () => {
scriptLoadedRef.current = true;
init();
};
document.head.appendChild(script);
}, [user]);
return <>{children}</>;
} Utilisation
Enveloppez votre app avec le provider :
// src/App.tsx
import { SupportDeskProvider } from './providers/SupportDeskProvider';
export default function App() {
return (
<SupportDeskProvider>
<YourRoutes />
</SupportDeskProvider>
);
} Bouton personnalisé
Avec showButton: false, le bouton flottant par défaut est masqué. Utilisez
votre propre UI pour ouvrir le widget :
function SupportButton() {
return (
<button onClick={() => window.SupportDesk?.toggle()}>
Contacter le support
</button>
);
} Badge messages non-lus
const [unread, setUnread] = useState(0);
useEffect(() => {
const unsubscribe = window.SupportDesk?.onUnreadChange(setUnread);
return () => unsubscribe?.();
}, []); 3. Intégration Vue 3
Créez un composable qui charge le widget côté client uniquement :
// src/composables/useSupportDesk.ts
import { watch } from 'vue';
import { useAuthStore } from '@/stores/auth';
const WIDGET_URL = import.meta.env.VITE_SUPPORTDESK_WIDGET_URL;
const APP_ID = import.meta.env.VITE_SUPPORTDESK_APP_ID;
const PUBLIC_KEY = import.meta.env.VITE_SUPPORTDESK_PUBLIC_KEY;
let scriptLoaded = false;
export function useSupportDesk() {
const auth = useAuthStore();
const init = (user: any) => {
if (!(window as any).SupportDesk) return;
(window as any).SupportDesk.destroy();
(window as any).SupportDesk.init({
appId: APP_ID,
apiKey: PUBLIC_KEY,
customer: {
externalId: user.id,
email: user.email,
name: user.name,
},
theme: { primaryColor: '#2563eb', showButton: false },
});
};
watch(
() => auth.user,
(user) => {
if (!user) return;
if (scriptLoaded) {
init(user);
return;
}
const script = document.createElement('script');
script.src = WIDGET_URL;
script.async = true;
script.onload = () => {
scriptLoaded = true;
init(user);
};
document.head.appendChild(script);
},
{ immediate: true },
);
const toggle = () => (window as any).SupportDesk?.toggle();
return { toggle };
} Utilisation dans un composant
<script setup lang="ts">
import { useSupportDesk } from '@/composables/useSupportDesk';
const { toggle } = useSupportDesk();
</script>
<template>
<button @click="toggle">Contacter le support</button>
</template> 4. Intégration Angular
Créez un service Injectable et initialisez-le dans votre AppComponent :
// src/app/support-desk.service.ts
import { Injectable, inject } from '@angular/core';
import { AuthService } from './auth/auth.service';
import { environment } from '../environments/environment';
@Injectable({ providedIn: 'root' })
export class SupportDeskService {
private auth = inject(AuthService);
private scriptLoaded = false;
init() {
this.auth.user$.subscribe((user) => {
if (!user) return;
if (this.scriptLoaded) {
this.initWidget(user);
return;
}
const script = document.createElement('script');
script.src = environment.supportDeskWidgetUrl;
script.async = true;
script.onload = () => {
this.scriptLoaded = true;
this.initWidget(user);
};
document.head.appendChild(script);
});
}
private initWidget(user: { id: string; email: string; name: string }) {
const SD = (window as any).SupportDesk;
if (!SD) return;
SD.destroy();
SD.init({
appId: environment.supportDeskAppId,
apiKey: environment.supportDeskPublicKey,
customer: {
externalId: user.id,
email: user.email,
name: user.name,
},
theme: { primaryColor: '#2563eb', showButton: false },
});
}
toggle() {
(window as any).SupportDesk?.toggle();
}
} Activation dans AppComponent
// src/app/app.component.ts
import { Component, OnInit, inject } from '@angular/core';
import { SupportDeskService } from './support-desk.service';
@Component({ ... })
export class AppComponent implements OnInit {
private supportDesk = inject(SupportDeskService);
ngOnInit() {
this.supportDesk.init();
}
} Bouton personnalisé
<button (click)="supportDesk.toggle()">
Contacter le support
</button> 5. Vanilla JS / HTML
Pour un site statique ou sans framework. Deux balises <script>
suffisent :
<script src="https://supportdesk-widget.vercel.app/v1/supportdesk-widget.js"></script>
<script>
SupportDesk.init({
appId: 'votre-app-id',
apiKey: 'pk_live_xxxxxxxxxxxx',
customer: {
externalId: 'user-123',
email: 'user@example.com',
name: 'Jean Dupont',
},
theme: {
primaryColor: '#2563eb',
position: 'bottom-right',
},
});
</script> Sans utilisateur connecté
Omettez simplement le champ customer :
SupportDesk.init({
appId: 'votre-app-id',
apiKey: 'pk_live_xxxxxxxxxxxx',
}); API JavaScript
Une fois le widget initialisé, l'objet window.SupportDesk expose les
méthodes suivantes :
| Méthode | Description |
|---|---|
| init(config) | Initialise le widget avec la config |
| destroy() | Démonte le widget complètement |
| open() | Ouvre le panneau |
| close() | Ferme le panneau |
| toggle() | Bascule ouvert/fermé |
| isOpen() | Retourne true si ouvert |
| onUnreadChange(cb) | S'abonne aux changements de non-lus. Retourne une fonction de désabonnement. |
Options de configuration
interface SupportDeskConfig {
// Obligatoire
appId: string; // Votre App ID
apiKey: string; // Public Key (pk_live_...)
// Optionnel — utilisateur connecté
customer?: {
externalId: string; // ID unique dans votre système
email: string;
name: string;
phone?: string;
metadata?: Record<string, unknown>;
};
// Optionnel — thème
theme?: {
primaryColor?: string; // Couleur accent (hex)
position?: 'bottom-right' | 'bottom-left'; // Position du bouton par défaut
showButton?: boolean; // Afficher le bouton flottant (défaut: true)
};
} Dépannage
Le widget ne se charge pas
- Vérifiez que
window.SupportDeskest défini dans la console - Vérifiez l'URL du script dans l'onglet Network du navigateur
- Assurez-vous que
init()est appelé après le chargement du script (script.onload)
Erreur 401 Unauthorized
Votre appId ou apiKey est incorrect, ou le customer.externalId
n'est pas fourni alors qu'il est requis pour les endpoints protégés.
Erreur CORS
Le backend SupportDesk autorise toutes les origines par défaut. Si vous voyez une
erreur CORS, c'est probablement que le widget ne s'est pas initialisé correctement.
Vérifiez que VITE_API_URL n'est pas surchargée.
Le Shadow DOM casse mon CSS
Il ne devrait pas — le widget est entièrement isolé. Si vous voyez des styles parasites, ouvrez un ticket avec un exemple reproductible.
Besoin d'aide ?
Utilisez SupportDesk sur cette page (icône en bas à droite) ou contactez-nous à innovartx@gmail.com.