Le widget
Une balise script, un bouton flottant, une fenêtre de feedback qui s'ajoute à n'importe quelle page. Tout ce qui suit, ce sont des réglages que vous pourriez vouloir changer, sans obligation.
La balise script
Collez ceci dans le HTML de chaque page où vous voulez recueillir des retours. Un bouton flottant apparaît dans le coin ; un clic ouvre la fenêtre de feedback.
<script
src="https://opini.dev/widget.js"
data-opini-key="pk_live_..."
data-opini-label="Send feedback"
data-opini-position="bottom-right"
data-opini-theme="light"
data-opini-accent="#C2410C"
defer></script>Opini tourne sur une autre origine ? Remplacez opini.dev par votre propre hôte. Le widget en déduit où envoyer les retours.
Options
Tous les réglages se trouvent sur la balise script, sous forme d'attributs data-*. Seule la clé est obligatoire.
| Attribut | Obligatoire | Rôle |
|---|---|---|
| data-opini-key | oui | La clé publique du widget de votre projet (pk_live_...). |
| data-opini-label | non | Texte du bouton flottant. Par défaut « Send feedback ». |
| data-opini-position | non | Le coin où placer le bouton. bottom-right (par défaut), bottom-left, top-right, top-left. |
| data-opini-theme | non | light (par défaut) ou dark. Choisissez ce qui va avec votre page. |
| data-opini-accent | non | La couleur de votre marque pour le bouton d'envoi et les contours de focus. N'importe quelle couleur CSS : hex, rgb() ou nom. |
| data-opini-base | non | Pointe vers un autre hôte d'API. Rarement utile : le script le déduit de son propre src. |
Personnalisation côté serveur
Les attributs data-* ci-dessus servent de repli. Au chargement, le widget récupère la configuration du projet depuis Opini, et un admin peut changer quelques textes sans toucher à la balise script de la page :
widget_label: le texte du bouton flottant.widget_headline: le titre de la fenêtre.widget_placeholder: le texte indicatif du champ.widget_submit_label: le bouton d'envoi.widget_thanks: le message de remerciement après l'envoi.accent_hex,widget_theme,widget_position: l'apparence.
Priorité : le serveur l'emporte, data-* comble les manques et les valeurs par défaut font le reste. Vous pouvez ainsi changer l'apparence de tous les widgets sur tous les sites depuis un seul endroit, sans demander à personne de recoller la balise.
Si la récupération de la configuration échoue (hors ligne, bloquée, CORS), le widget se charge quand même avec les attributs et les valeurs par défaut. L'appel réseau ne bloque jamais rien.
Identifier les utilisateurs
Indiquez à Opini qui envoie le retour, pour qu'il arrive dans le tri avec un nom et tout ce que vous voulez transmettre.
Le widget demande un nom et un e-mail à chaque visiteur pour que votre équipe puisse répondre. Quand vous passez name et email ici, ces champs sont masqués.
window.opini.identify({
email: "[email protected]",
name: "Ada Lovelace",
plan: "pro",
signed_up_at: "2024-11-02"
});Quelques remarques :
email: visible uniquement dans le tri. Jamais affiché sur les pages publiques.name: utilisé comme nom affiché dans le tri et les vues admin.- Tout le reste (offre, date d'inscription, etc.) suit comme contexte supplémentaire dans le panneau de détail du tri.
Appelez-la dès que vous savez qui est l'utilisateur : au chargement, après la connexion, peu importe. Le dernier appel avant l'envoi l'emporte.
Pour filtrer sur une de ces valeurs dans la liste Feedback, utilisez le filtre Contexte avec une clé pointée, comme identify.plan.
Thème
Deux réglages. data-opini-theme choisit clair (par défaut, fond blanc) ou sombre (inversé). Le widget vit dans un shadow root : le CSS de votre page ne peut pas déborder dessus et le casser.
data-opini-accent est la couleur de votre marque : elle colore le bouton d'envoi et les contours de focus. Toute couleur CSS valide fonctionne.
Questions de suivi
Le tri n'est pas une boîte à sens unique. Chaque retour a un bouton question de suivi dans la vue admin : posez une question et la personne reçoit par e-mail un lien pour répondre. Sans compte ni connexion, juste une page avec l'extrait du retour, la question et un champ de texte.
La réponse revient sur la même ligne. Les liens expirent après 30 jours et ne servent qu'une fois. Page complète : Questions de suivi.
Accessibilité
Tout ce que vous pouvez attendre est déjà pris en charge :
- La fenêtre s'annonce aux lecteurs d'écran comme une boîte de dialogue avec un titre.
- Au clavier, on parcourt le formulaire sans que le focus ne s'échappe vers la page ; Échap ferme la fenêtre et rend le focus au bouton qui l'a ouverte.
- Le bouton flottant est un vrai bouton, pas une div déguisée, et aucune cible tactile n'est plus petite qu'un doigt.
- La couleur d'accent colore les contours de focus : au clavier, on sait toujours où on est.
Le retirer
Supprimez la balise script. Le widget ne touche ni au localStorage, ni au sessionStorage, ni aux cookies de votre page : rien ne reste derrière.
Avancé
Vous n'en aurez sans doute pas besoin. Ouvrez si c'est le cas.
Vous utilisez une Content Security Policy stricte ?
Voici ce qu'il faut autoriser (si Opini est hébergé sur opini.dev) :
Content-Security-Policy:
script-src 'self' https://opini.dev;
connect-src 'self' https://opini.dev https://*.r2.cloudflarestorage.com;
img-src 'self' blob:;
style-src 'self' 'unsafe-inline';Le widget injecte ses styles en ligne dans son shadow root : 'unsafe-inline' est donc nécessaire sur style-src tant que le chargement des styles par nonce n'est pas disponible. Pas d'eval, pas d'images externes, pas de frames.
Les images jointes sont envoyées directement au stockage (l'hôte R2) et affichent un aperçu local (blob:). Si votre politique impose les Trusted Types, ajoutez opini-widget à trusted-types.
Taille exacte
Le widget est un seul script : aucune dépendance, aucun chargement différé, rien à brancher en dehors de la balise.
- Compressé (gzip) : ~4.2 KB
- Non compressé : ~12 Ko