Widget web de collecte de feedback utilisateur, isolé en Shadow DOM.
Client du service feedback-service.
La spécification du projet vit dans ce dépôt-là (SPEC.md, §5) — c'est la source de vérité.
Une seule balise, aucune dépendance :
<script src="https://feedback.exemple.com/w.js"
data-app="mon-app"
data-key="pk_live_xxx"
data-version="1.4.2"></script>Un bouton flottant s'injecte en bas à droite.
| Attribut | Obligatoire | Rôle |
|---|---|---|
data-key |
oui | Clé publique pk_. Elle est destinée à être publique. |
data-version |
non | Version de l'application, jointe à chaque feedback (unknown par défaut). |
data-app |
non | Nom de l'application, à titre indicatif. Le service déduit l'application de la clé. |
data-endpoint |
non | Adresse du service. Par défaut, l'origine d'où le script a été chargé. |
data-auto-button |
non | false masque le bouton flottant ; le panneau ne s'ouvre alors que par l'API. |
data-endpoint est nécessaire dès que le widget est servi par un CDN et l'API par un autre domaine.
Pour les applications qui préfèrent leur propre point d'entrée :
Feedback.open(); // Ouvre le panneau
Feedback.close(); // Le ferme
Feedback.identify("utilisateur-42"); // Associe une référence aux feedbacks suivantsidentify attend une référence opaque, décidée par l'application. Ne pas y mettre
d'adresse e-mail ni de donnée personnelle : le service ne l'interprète jamais.
{
"appVersion": "1.4.2",
"type": "bug",
"title": "Le bouton Enregistrer ne répond plus",
"body": "Un clic ne déclenche rien.",
"userRef": "utilisateur-42",
"context": {
"url": "...", "referrer": "...", "userAgent": "...",
"language": "fr-FR", "viewport": "1440x900", "screen": "2560x1440",
"timezone": "Europe/Paris"
}
}Le contexte est collecté automatiquement — l'utilisateur ne connaît généralement pas ces informations. S'il dépasse la limite acceptée par le service (8 192 caractères), il est réduit à l'URL et au user-agent plutôt que de faire échouer l'envoi.
Tout le widget vit dans un Shadow DOM (:host { all: initial }) : le CSS de la page hôte
ne l'atteint pas, et le sien ne fuit pas vers la page. C'est vérifié par un test qui applique
des styles agressifs à la page hôte et compare le rendu.
| Réponse du service | Ce que voit l'utilisateur |
|---|---|
201 |
Confirmation, puis fermeture automatique |
400 |
Le détail renvoyé par le service, désignant le champ en cause |
401 / 403 |
Message de configuration incorrecte — la saisie est conservée |
429 |
Invitation à réessayer plus tard |
5xx, réseau |
Invitation à réessayer |
La saisie n'est jamais perdue sur échec. Un état d'attente est affiché pendant l'envoi :
le service peut mettre 10 à 20 secondes à répondre après une période d'inactivité
(cold start Cloud Run, cf. SPEC.md §8).
npm install
npm run build # produit dist/w.js minifié (~9 ko)
npm test # 19 tests de bout en bout dans un vrai ChromiumLes tests interceptent leurs propres requêtes : aucun serveur n'est nécessaire.
Si un Chromium est déjà installé sur la machine, le désigner évite un téléchargement :
CHROMIUM_PATH=/chemin/vers/chromium npm testdemo/index.html installe le widget dans une page aux styles volontairement agressifs.
Elle pointe vers l'instance Cloud Run de feedback-service avec la clé publique de
l'application feedback-widget-js-demo : l'aller-retour complet fonctionne sans rien
modifier. Cette clé est versionnée ici sans précaution particulière, comme n'importe
quelle clé pk_ — elle est destinée à vivre dans le HTML de pages publiques, n'ouvre
que la soumission, et aucune route de lecture ne lui répond.
src/w.js est directement servable : c'est du JavaScript sans étape de compilation,
ce qui permet une distribution par jsDelivr depuis ce dépôt, sans hébergement dédié.
dist/w.js n'est qu'une version minifiée, régénérable par npm run build, et n'est
pas versionnée.
Pour une installation cliente, préférer un tag Git plutôt que @main :
<script src="https://cdn.jsdelivr.net/gh/JeanGarf/feedback-widget-js@v0.1.0/src/w.js"
data-app="mon-app"
data-key="pk_live_xxx"></script>@main est re-résolu régulièrement par jsDelivr : un push cassant impacterait aussitôt
tous les sites clients. Un tag est en revanche mis en cache indéfiniment par le CDN, ce
qui garantit à la fois la stabilité des sites déjà installés et des temps de réponse
optimaux. Chaque publication d'une nouvelle version doit donc être accompagnée d'un tag
Git (git tag vX.Y.Z sur main, correspondant à la version de package.json).