Widget de réservation
Le widget peut être intégré de deux façons :
- Balise de script — un unique extrait HTML qui affiche le formulaire de réservation. Aucun JavaScript n’est nécessaire. C’est l’extrait fourni dans le back-office du restaurant.
- API JavaScript — le même widget, créé et piloté depuis votre propre code. À utiliser lorsque la page doit transmettre du contexte, réagir à des événements, ou gérer le cycle de vie du widget.
Balise de script
Section intitulée « Balise de script »Ajoutez l’extrait à l’endroit où le formulaire de réservation doit apparaître :
<div id="service-widget"></div><script src="https://app.useservice.app/widget/widget.js" data-slug="chez-marie" data-mode="inline" async></script>data-slug identifie le restaurant. Le back-office affiche l’extrait avec le
slug correct sous Paramètres → Widget.
Le widget charge les disponibilités du restaurant, prend la réservation et la confirme. Aucune autre intégration n’est nécessaire.
Attributs
Section intitulée « Attributs »| Attribut | Valeurs | Description |
|---|---|---|
data-slug | Slug du restaurant | Obligatoire. Identifie le restaurant. |
data-mode | inline, sticky, popover | Mode de présentation. inline par défaut. |
data-position | bottom-right, top-left, etc. | Ancrage du déclencheur flottant. sticky uniquement. |
Modes de présentation :
| Mode | Comportement |
|---|---|
inline | S’affiche dans le flux de la page, à l’intérieur de #service-widget. |
sticky | Affiche un bouton Réserver flottant qui ouvre le formulaire. |
popover | N’affiche rien jusqu’à l’ouverture, par un élément déclencheur ou par l’API JavaScript. |
data-mode="manual" était l’ancien nom de popover. Il a été retiré le
6 août 2026 : il se comporte désormais comme inline, au même titre que toute
valeur non reconnue. Le back-office émet popover, qui est aussi le nom employé
par l’API JavaScript.
Éléments déclencheurs
Section intitulée « Éléments déclencheurs »En mode popover, tout élément portant l’attribut data-service-widget-open
ouvre le widget :
<button data-service-widget-open>Réserver une table</button>L’élément est stylé par votre page. Aucun JavaScript n’est nécessaire.
Charger le bundle
Section intitulée « Charger le bundle »https://app.useservice.app/widget/widget.js est une adresse stable qui
redirige vers un fichier dont le nom porte une empreinte de contenu. Ce fichier
est mis en cache un an et ne change jamais ; la redirection est mise en cache
cinq minutes, ce qui est le délai qu’une mise en production met à atteindre les
pages qui portent déjà le widget.
Chargez-le depuis cette adresse. Une copie servie depuis votre propre domaine, une copie compilée dans votre bundle, et un plugin de cache de CMS qui réécrit l’URL figent tous la version que vous avez prise et cessent de recevoir les correctifs.
Quand le script s’exécute
Section intitulée « Quand le script s’exécute »async est pris en charge et c’est ce qu’émet l’extrait du back-office.
Les attributs data-* sont lus sur la balise de script qui a chargé le bundle :
ils doivent donc figurer sur cette balise et pas sur une autre.
Le script installe window.ServiceWidget pendant son exécution, et monte le
widget de sa propre balise une fois le document analysé. Avec async, le moment
où il s’exécute n’est pas ordonné par rapport à vos scripts en ligne : le code
qui appelle ServiceWidget.create() s’exécute donc depuis l’événement load —
comme dans l’exemple ci-dessous — ou depuis le onload de la balise de script.
ServiceWidget.version indique la version du bundle. Une seule version est
publiée à la fois ; il n’y a pas de version à épingler ni de montée de version à
planifier.
API JavaScript
Section intitulée « API JavaScript »La balise de script installe window.ServiceWidget. ServiceWidget.create()
renvoie une instance :
<script src="https://app.useservice.app/widget/widget.js" async></script><script> window.addEventListener("load", async () => { const widget = ServiceWidget.create({ slug: "chez-marie", mode: "popover" }); await widget.ready;
widget.on("reservation:confirmed", ({ reservation }) => { console.log("réservé", reservation.publicId); });
document.querySelector("#book").addEventListener("click", () => widget.open()); });</script>Options de create()
Section intitulée « Options de create() »| Option | Type | Description |
|---|---|---|
slug | string | Obligatoire. Identifie le restaurant. |
mode | inline | popover | sticky | Mode de présentation. inline par défaut. |
container | string | HTMLElement | Point de montage pour inline. #service-widget par défaut. |
locale | string | Langue initiale du client. Une valeur invalide retombe sur fr. |
position | string | Ancrage du déclencheur flottant. sticky uniquement. |
Instances
Section intitulée « Instances »Chaque appel à create() renvoie une instance indépendante. open(),
close(), setContext(), setGuestToken() et on() sont des méthodes de
cette instance, et non de ServiceWidget.
Une page peut porter plusieurs instances — le site d’un groupe listant plusieurs restaurants — et l’objet global ne peut en désigner aucune individuellement.
Comportements à prendre en compte
Section intitulée « Comportements à prendre en compte »widget.ready se résout lorsque l’instance est montée. Les méthodes appelées
avant ce moment sont honorées plutôt qu’ignorées : l’attendre est facultatif.
La promesse se résout également si l’instance est détruite avant d’être montée,
elle ne reste donc jamais en attente.
create() lève une exception immédiatement lorsque mode: "inline" et que son
conteneur est introuvable. Un sélecteur incorrect apparaît à l’appel, et non
sous la forme d’un formulaire qui ne s’affiche pas.
on() renvoie une fonction de désabonnement. Appelez-la lorsque le composant
abonné est retiré.
Événements
Section intitulée « Événements »widget.on("reservation:created", ({ reservation }) => {});widget.on("reservation:confirmed", ({ reservation }) => {});reservation:created se déclenche pour toute réservation qui atteint une issue,
y compris les réservations en attente de validation par le restaurant et celles
qui retiennent une table dans l’attente d’une empreinte bancaire.
reservation:confirmed ne se déclenche que lorsque le client détient une table
confirmée.
Envoyer un message de confirmation sur reservation:created finira par notifier
un client qui détient une option non réglée plutôt qu’une table.
La charge utile de l’événement contient publicId et aucune coordonnée.
publicId est la clé de jointure pour l’API et pour les
webhooks, qui s’exécutent tous deux côté serveur.
Le catalogue complet figure dans Événements.
Où sont stockées les réservations
Section intitulée « Où sont stockées les réservations »Le widget écrit directement dans le calendrier du restaurant. Il n’existe aucune étape où votre site reçoit une réservation puis la transmet, et aucune clé d’API n’intervient : consulter les disponibilités et réserver sont des opérations publiques sur un seul restaurant.
Pour recevoir les réservations dans d’autres systèmes, lisez-les via l’API ou abonnez-vous aux webhooks. C’est le chemin qu’emprunte aussi une réservation prise par téléphone.