Aller au contenu

Liens profonds

Un lien profond ouvre la page de réservation autonome avec le parcours déjà positionné. C’est l’intégration des supports qui n’ont aucune page où s’intégrer : e-mail, SMS, QR codes, imprimés, un outil marketing qui ne sait émettre qu’un lien.

https://book.useservice.app/r/chez-marie?date=2026-09-03&party=4&shift=1

/r/ suivi de l’identifiant du restaurant. Les paramètres sont le transport URL décrit dans transmettre le contexte — mêmes noms, mêmes formats, et la même règle : une valeur qui ne s’analyse pas est ignorée.

La page de réservation est servie avec frame-ancestors 'none' : un navigateur refuse donc de l’afficher dans une <iframe>. Un lien l’ouvre ; une incorporation donne un cadre vide et une erreur dans la console.

Pour mettre la réservation sur votre propre page, incorporez le widget plutôt que la page — voir commencer. C’est le même produit, et c’est la surface conçue pour s’exécuter dans le document de quelqu’un d’autre.

data-* exige une balise de script et setContext() exige une de vos pages : sur la page autonome, il n’y a donc aucune priorité à arbitrer. L’URL n’est pas la source la plus prioritaire, elle est la seule.

Cela change ce que le lien doit porter. Tout ce avec quoi le parcours doit démarrer doit s’y trouver, car rien d’autre sur ce support ne pourra le fournir ensuite.

?t= transporte le jeton signé, opaque et entier :

https://book.useservice.app/r/chez-marie?date=2026-09-03&t=eyJpc3MiOiJpdmtfcmVm…

C’est le seul support qui le lit. Un widget intégré ignore le ?t= présent dans l’URL de la page qui le porte. Une page qui porte la balise de script dispose de JavaScript, donc de setGuestToken(), qui ne laisse aucune copie derrière lui : y lire un jeton depuis la barre d’adresse déposerait un identifiant vivant dans les journaux de cette page sans rien apporter en échange.

L’URL transporte le jeton et jamais les champs. Aucun nom de paramètre ne correspond à un nom, un e-mail ou un téléphone : l’identité ne peut donc pas atterrir dans un lien par accident — ?email= n’est lu par personne.

Un jeton dans le chemin est tout autre chose. /r/chez-marie/AbC123… est le lien de gestion de réservation émis par Service, envoyé au client après sa réservation. L’identité fournie par votre site voyage dans la chaîne de requête, sous le nom t.

Une URL se copie. L’historique du navigateur la conserve, les clients de messagerie et les passerelles SMS la conservent, la réécriture de liens des outils marketing et des proxys d’entreprise la conserve. Un jeton est un identifiant vivant tant qu’il est valide : la question n’est donc pas qui peut en détenir une copie, mais pendant combien de temps.

Deux choses sont vraies de notre côté, et aucune n’est une garantie générale :

  • Le journal d’accès de la page de réservation masque t et laisse lisibles tous les autres paramètres. C’est le journal du widget, et lui seul.
  • Referrer-Policy: strict-origin-when-cross-origin fait que les requêtes de la page de réservation vers d’autres origines n’envoient que l’origine, jamais la chaîne de requête.

Tout ce qui se trouve entre votre système et le navigateur du client échappe aux deux. Ce qui couvre le reste, c’est la durée de vie de 15 minutes : un jeton qui fuite est un jeton qui a cessé de fonctionner quelques minutes plus tard.

Générez donc le jeton au moment où le lien est envoyé, et non au moment où la campagne est construite.

Un QR code sur un chevalet de table ou une affiche survit à son jeton de plusieurs mois. Chaque client qui le scanne présente un jeton expiré et se voit annoncer que la session a expiré — un message exact et inutile, qui remplace le parcours de réservation ordinaire qu’il venait chercher.

Les liens imprimés portent du contexte et aucune identité :

https://book.useservice.app/r/chez-marie?party=2

Le parcours charge les disponibilités à son ouverture, parfois longtemps après l’écriture du lien. Un lien vers un jour complet ouvre sur ce jour et annonce qu’il est complet.

Lorsque le jeton verrouille la date, le client ne peut pas en changer et la page ne peut qu’énoncer le résultat. return_url est alors la seule sortie — voir identifier le client.

Chaque paramètre est validé séparément, et un paramètre invalide est ignoré : jamais appliqué à moitié, jamais fatal. ?date=n-importe-quoi&party=4 ouvre sur quatre couverts et le calendrier ordinaire.

Un lien passé par un réécriveur, tronqué par un client de messagerie ou modifié à la main par le client ouvre quand même la page de réservation.

?locale= choisit la langue dans laquelle la page se charge, parmi les onze langues client. Toute autre valeur retombe sur le français plutôt que d’afficher un parcours à moitié traduit.

Un client qui a déjà choisi une langue sur la page de réservation conserve son choix. La préférence enregistrée l’emporte sur le lien, au motif que le client l’a choisie et que l’auteur du lien, non.