Aller au contenu

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.

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.

AttributValeursDescription
data-slugSlug du restaurantObligatoire. Identifie le restaurant.
data-modeinline, sticky, popoverMode de présentation. inline par défaut.
data-positionbottom-right, top-left, etc.Ancrage du déclencheur flottant. sticky uniquement.

Modes de présentation :

ModeComportement
inlineS’affiche dans le flux de la page, à l’intérieur de #service-widget.
stickyAffiche un bouton Réserver flottant qui ouvre le formulaire.
popoverN’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.

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.

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.

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.

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>
OptionTypeDescription
slugstringObligatoire. Identifie le restaurant.
modeinline | popover | stickyMode de présentation. inline par défaut.
containerstring | HTMLElementPoint de montage pour inline. #service-widget par défaut.
localestringLangue initiale du client. Une valeur invalide retombe sur fr.
positionstringAncrage du déclencheur flottant. sticky uniquement.

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.

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é.

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.

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.