Disponible · v1

Le pont entre votre site Web et son application.

Un petit SDK JavaScript versionné pour coordonner les titres de page, la navigation, les badges, le cycle de vie des applications, le partage, les notifications et d'autres comportements natifs, sans service backend public.

app-bridge.js
const context = await SiteToApp.ready();

if (context.available) {
  await SiteToApp.page.setTitle('Your cart');
  await SiteToApp.navigation.setBadge('cart', 3);
}
Pas de clé, de jeton ou de point de terminaison REST public
But

Un site Web, avec des moments compatibles avec les applications.

Le SDK est une amélioration progressive facultative. Vos pages possèdent toujours le contenu, le routage, les comptes, les paniers et les règles métier. Le shell natif possède les applications Chrome et les intégrations d'appareils. Le SDK transmet de petits messages validés entre les deux.

Aucun service REST public SiteTo.App n’est impliqué. Les sites Web n'ont pas besoin d'une clé SiteTo.App et le SDK ne doit jamais contenir d'informations d'identification de magasin, de secrets clients ou de jetons de compte privilégié.

Titres de pages contextuels

Laissez une page de paiement, de compte ou d'article mettre à jour l'en-tête natif tout en gardant le titre du navigateur correct.

Badges de navigation en direct

Transmettez immédiatement une valeur connue ou lisez un panier, une boîte de réception ou un nombre de réservations à partir d'une URL de même origine.

Navigation tenant compte de l'itinéraire

Gardez l’élément de navigation natif actif aligné sur les pages traditionnelles et les itinéraires d’application d’une seule page.

Événements du cycle de vie

Actualisez l'état du site Web obsolète lorsque l'application reprend, se reconnecte ou s'ouvre à partir d'une notification ou d'un lien profond.

Actions natives

Utilisez la feuille de partage système, les invites d'autorisation, les paramètres et les commentaires haptiques subtils lorsqu'ils sont pris en charge.

Comportement de navigateur sécurisé

Chaque fonctionnalité dispose d'une solution de secours ou d'une absence de fonctionnement du navigateur, de sorte qu'une seule base de code de site Web continue de fonctionner partout.

Disponibilité et configuration

Un script, explicitement versionné.

Ajoutez le script CDN à un site Web ordinaire ou installez le package npm dans une application groupée. Les deux exposent le même comportement et la même version de protocole.

Script CDNv1
<script
  src="https://cdn.siteto.app/sdk/v1/sitetoapp.min.js"
  defer
></script>
Module ESv1
import { SiteToApp } from '@sitetoapp/web-sdk';

Les versions majeures se trouvent dans l'URL et le contrat de package. Les ajouts ininterrompus peuvent être expédiés dans les v1; des méthodes renommées, des charges utiles modifiées ou un comportement de repli différent nécessitent v2.

État de préparation et contexte

Détectez les capacités, pas les agents utilisateurs.

SiteToApp.ready() commence une poignée de main avec le shell natif et se résout en un AppContext. Il doit également être résolu dans un navigateur normal, afin que le code de l'application ne se bloque jamais en attendant un pont qui n'est pas présent.

Javascriptv1
const context = await SiteToApp.ready({ timeout: 1500 });

if (!context.available) {
  // Normal browser: keep using your existing web behavior.
  return;
}

await SiteToApp.page.setTitle('Order details');
await SiteToApp.navigation.setActive('orders');
Champ de contexteValeurRaison
disponiblebooléenSi un shell natif a effectué une poignée de main valide.
plate-formeiOS | androïde | la toileLe runtime actif ; jamais déduit de l'agent utilisateur.
appVersionchaîne | nulLa version de l'application native installée, lorsqu'elle est disponible.
sdkVersionchaîneLa version du SDK du site Web chargée.
protocolVersionnuméro | nulLe contrat relais négocié avec l'application.
capacitéschaîne[]Commandes prises en charge telles que navigation.badge ou share.
colorSchemelumière | sombreL'apparence native actuelle.
safeAreahaut, droite, bas, gaucheEncarts en pixels CSS pour des mises en page plein écran personnalisées.
Le code de fonctionnalité doit être vérifié context.capabilities lorsque la prise en charge varie selon la version de l'application installée. Les contrôles de plateforme sont un dernier recours.
Titres et état des pages

Gardez l'en-tête natif dans son contexte.

Une page peut modifier l'en-tête de l'application à mesure que les clients parcourent les produits, les articles, les sections du compte ou le paiement. Par défaut, setTitle met à jour à la fois l'en-tête natif et document.title l'historique du navigateur reste donc également utile.

Javascriptv1
// Update both the document title and the app header.
await SiteToApp.page.setTitle('Your cart');

// Change only the native header.
await SiteToApp.page.setTitle('Checkout', {
  document: false,
  native: true,
});

// Return to the title derived from the page or app configuration.
await SiteToApp.page.resetTitle();
page.setLoading(boolean)

Connectez une transition de site Web à l’indicateur de chargement du shell. L'application doit toujours appliquer un délai d'expiration automatique afin qu'une page ne puisse pas la laisser fonctionner indéfiniment.

page.setPullToRefresh(boolean)

Désactivez l'extraction pour actualiser pour dessiner des surfaces, des cartes ou des interactions lorsque le geste entre en conflit avec le comportement de la page.

Insignes de navigation

Montrez le décompte qui compte maintenant.

Les éléments de navigation utilisent des ID stables configurés dans le générateur SiteTo.App, tels que cart, inbox, ou bookings. Les étiquettes peuvent changer, mais ces identifiants restent le contrat entre le site Web et l'application.

Définir une valeur connue

Javascriptv1
// Numbers are formatted by the native app: 100 becomes “99+”.
await SiteToApp.navigation.setBadge('cart', 3);

// Zero, null, or false hides the badge.
await SiteToApp.navigation.setBadge('cart', 0);

// Short status labels are also allowed.
await SiteToApp.navigation.setBadge('inbox', 'NEW');

Mettre à jour à partir d'une URL

Un observateur récupère dans le contexte du site Web, et non à partir d'un service SiteTo.App distinct. Les URL relatives de même origine sont recommandées car elles conservent intacts les cookies normaux du site et les règles de sécurité.

Exemple de panier de style Shopifyv1
const cartBadge = SiteToApp.navigation.watchBadge('cart', {
  url: '/cart.js',
  jsonPath: 'item_count',
  interval: 30_000,
  refreshOn: ['ready', 'resume', 'focus', 'urlchange'],
  hideWhenZero: true,
  stale: 'keep',
});

// Refresh after a local add-to-cart action.
await cartBadge.refresh();

// Stop fetching when this page no longer owns the badge.
cartBadge.stop();
OptionDéfautComportement
URLrequisHTTPS ou URL relative renvoyant du JSON ou du texte brut.
jsonPathaucunChemin de points tel que cart.item_count. Obligatoire lorsque JSON n’est pas lui-même la valeur du badge.
intervalledésactivéIntervalle d'interrogation en millisecondes, avec un minimum de 15 secondes.
refreshOnprêt, reprenezToute combinaison de prêt, CV, focus et changement d'URL.
informations d'identificationmême origineUtilise le mode Récupérer les informations d'identification du navigateur. Les requêtes d’origine croisée nécessitent toujours CORS.
temps mort5000Temps de récupération maximum en millisecondes.
hideWhenZerovraiMasquez le badge lorsque le résultat mappé est 0, nul ou faux.
viciégarderConserver la dernière valeur valide après une erreur ; l’alternative est claire.
  • Les valeurs numériques s'affichent de 1 à 99 ; les valeurs plus grandes utilisent le natif 99+ treatment.
  • Les valeurs de texte sont tronquées, nettoyées et limitées à quatre caractères visibles.
  • L'interrogation s'interrompt pendant que l'application est en arrière-plan et reprend avec une actualisation immédiate.
  • Les demandes qui se chevauchent sont annulées ; la réponse valide la plus récente l'emporte.
  • Les échecs HTTP, d'analyse et de mappage émettent sdk:error sans casser la page.
Actions natives

Utilisez le comportement de l’appareil là où il mérite sa place.

Les actions natives doivent améliorer un flux Web existant et non devenir une condition nécessaire à l'utilisation du site Web. Les invites d'autorisation doivent suivre une action claire de l'utilisateur et expliquer d'abord leur valeur dans la page.

Partage, notifications et haptiquev1
await SiteToApp.share({
  title: 'Spring collection',
  text: 'These just arrived.',
  url: window.location.href,
});

// Must be called from a user click or tap.
const permission = await SiteToApp.notifications.requestPermission();

// Use sparingly for confirmation, not decoration.
await SiteToApp.haptics.impact('light');

Partager avec une solution de secours utile

Utilisez la feuille de partage native dans l'application, navigator.share le cas échéant, puis un repli du presse-papiers après une action de l'utilisateur.

Gardez le statut d'autorisation simple

Retour default, granted, denied, ou unsupported. N’exposez jamais un jeton push brut au code de la page.

Ouvrir délibérément les liens externes

Les URL approuvées en interne restent dans l'application. Les liens HTTPS externes s'ouvrent dans le navigateur système, sauf indication contraire dans la configuration de l'application.

Rétroaction physique à limite de débit

Les haptiques sont ignorées lorsqu'elles ne sont pas prises en charge et limitées de manière native pour empêcher une page de produire des commentaires perturbateurs répétés.

Événements d'application

Laissez le site Web répondre au cycle de vie des applications.

Les événements circulent du shell natif vers le SDK après validation du schéma et de l’origine. Les gestionnaires reçoivent des charges utiles publiques minimales et renvoient une fonction de désabonnement afin que les sites basés sur des composants puissent les nettoyer.

Abonnements à des événementsv1
const unsubscribe = SiteToApp.on('app:resume', () => {
  cartBadge.refresh();
});

SiteToApp.on('navigation:reselect', ({ itemId }) => {
  if (itemId === 'home') window.scrollTo({ top: 0, behavior: 'smooth' });
});

SiteToApp.on('notification:opened', ({ url }) => {
  if (url) window.location.assign(url);
});

// Remove a listener when its owning component unmounts.
unsubscribe();
app:resume

L'application est revenue au premier plan. Actualisez les données des pages sensibles au facteur temps et les badges surveillés.

app:pause

L'application est passée en arrière-plan. Suspendez les travaux coûteux qui ne sont pas déjà gérés par le navigateur.

navigation:reselect

L'utilisateur a de nouveau appuyé sur l'élément de navigation natif actuellement actif. Fait généralement défiler un flux vers le haut.

route:open

Le shell a reçu un lien profond de confiance que le routeur de pages doit gérer sans rechargement complet.

notification:opened

L'utilisateur a ouvert une notification push. La charge utile contient une URL dans l'application approuvée et des métadonnées publiques facultatives.

network:change

La connectivité a changé entre en ligne et hors ligne. Le navigateur reste la source de vérité pour le succès réel de la récupération.

appearance:change

L’aspect clair ou sombre d’origine a changé. La charge utile inclut le nouveau jeu de couleurs.

sdk:error

Un observateur, une commande de pont ou une validation de message a échoué. Destiné aux diagnostics, pas à la journalisation sensible.

Solutions de secours du navigateur

Le site Internet doit rester un site Internet.

Ne pas être à l’intérieur de l’application est un état normal et non une exception. Le SDK doit éviter le bruit de la console et renvoyer des résultats prévisibles lorsque son homologue natif est absent.

FonctionnalitéComportement normal du navigateur
prêtRésout avec available: false et platform: web après le délai d'attente.
page.setTitleMet à jour document.title lorsque le document est activé ; rapports de livraison natifs faux.
badges et état de l'articleNe pas récupérer ou restituer par défaut. Retour livré : faux sans jeter.
navigation.openUtilise location.assign, location.replace ou window.open en fonction de la cible.
navigation.backUtilise history.back lorsque l'historique du navigateur est disponible.
partagerUtilise navigator.share, puis le presse-papiers après un geste de l'utilisateur.
avisRetours non pris en charge ; il ne remplace pas le système de notification du navigateur.
haptiqueNo-op sécurisé avec livré : faux.
Les commandes doivent aboutir à un petit résultat tel que { delivered: false, reason: 'not-in-app' }. Les arguments invalides et les refus natifs utilisent typé SiteToAppError codes.
surface v1

Référence complète de la méthode.

SiteToApp.ready(options?)

Attendez la poignée de main, puis résolvez le AppContext actuel. Cela résout toujours; un navigateur normal renvoie disponible : false.

SiteToApp.getContext()

Renvoie la dernière plate-forme négociée, les versions, les valeurs de zone de sécurité, le jeu de couleurs et la liste des capacités.

SiteToApp.isAvailable()

Signale de manière synchrone si un pont natif validé est actuellement connecté.

SiteToApp.page.setTitle(title, options?)

Mettez à jour document.title, l'en-tête natif ou les deux. Les titres vides sont rejetés.

SiteToApp.page.setLoading(loading)

Afficher ou masquer l'indicateur de chargement du shell pour une transition de page ou une action de longue durée.

SiteToApp.page.setPullToRefresh(enabled)

Activez ou désactivez l’extraction native pour actualiser pour les écrans où le geste est approprié.

SiteToApp.navigation.setBadge(itemId, value)

Définir un badge d'élément de navigation configuré. Zéro, null et false l'effacent.

SiteToApp.navigation.watchBadge(itemId, options)

Récupérez et mappez une valeur de badge sur des déclencheurs de cycle de vie ou un intervalle contrôlé. Renvoie les contrôles d’actualisation et d’arrêt.

SiteToApp.navigation.setActive(itemId)

Sélectionnez un élément de navigation natif configuré sans naviguer sur le site Web.

SiteToApp.navigation.syncWithLocation(rules)

Observez l'historique du navigateur et gardez l'élément actif aligné avec les règles de correspondance d'URL. Renvoie une fonction de désabonnement.

SiteToApp.navigation.setItem(itemId, state)

Mettez à jour l’étiquette, la visibilité ou l’état activé d’un élément configuré existant.

SiteToApp.navigation.open(url, options?)

Ouvrez une URL interne approuvée dans la vue Web actuelle ou une URL HTTPS externe dans le navigateur système.

SiteToApp.navigation.back()

Demandez au shell de revenir en arrière, en passant à l'historique du navigateur lorsqu'aucune route native n'est disponible.

SiteToApp.share(data)

Ouvrez la feuille de partage native, avec les solutions de secours navigator.share et clipboard sur le Web.

SiteToApp.notifications.requestPermission()

Demandez l'autorisation de notification après un geste de l'utilisateur et renvoyez le statut résultant.

SiteToApp.notifications.openSettings()

Ouvrez les paramètres du système d'exploitation pour cette application lorsque l'autorisation a été précédemment refusée.

SiteToApp.haptics.impact(style)

Demandez des commentaires sur les impacts légers, moyens ou importants. Il s'agit d'une opération non opérationnelle lorsqu'elle n'est pas prise en charge.

SiteToApp.on(event, handler)

Abonnez-vous à un événement d'application validé et recevez une fonction de désabonnement.

SiteToApp.once(event, handler)

Abonnez-vous au prochain événement correspondant, puis supprimez automatiquement le gestionnaire.

Erreurs de frappe : INVALID_ARGUMENT, UNSUPPORTED, NOT_ALLOWED, TIMEOUT, FETCH_FAILED, PROTOCOL_MISMATCH, et NATIVE_ERROR.

Protocole de pont

Une petite enveloppe de message reconnu.

La couche JavaScript normalise les détails du transport de la plateforme. Dans l'application, les messages transitent via le transport React Native WebView sous forme de JSON sérialisé via window.ReactNativeWebView.postMessage. L'enveloppe est indépendante de ce transport.

Du site Web à l'application

Enveloppe de commandev1
{
  "channel": "sitetoapp",
  "protocolVersion": 1,
  "id": "sta_01J8ZQ6JY1",
  "type": "navigation.badge.set",
  "payload": {
    "itemId": "cart",
    "value": 3
  },
  "timestamp": 1789584000000
}

Reconnaissance de l'application

Enveloppe de réponsev1
{
  "channel": "sitetoapp",
  "protocolVersion": 1,
  "type": "response",
  "replyTo": "sta_01J8ZQ6JY1",
  "ok": true,
  "payload": null
}

Application vers le site Web

Événement natif validév1
// Native shell → website. Internal SDK method; not public surface.
window.SiteToApp.__receive({
  channel: 'sitetoapp',
  protocolVersion: 1,
  type: 'event',
  event: 'app:resume',
  payload: { occurredAt: Date.now() },
});
  • Le SDK commence par bridge.hello; l'application répond avec les versions et capacités de protocole prises en charge.
  • Chaque commande reçoit un identifiant unique. Les commandes qui nécessitent une confirmation reçoivent une réponse faisant référence à cet ID.
  • Le délai d'expiration d'accusé de réception par défaut est de deux secondes. Les réponses tardives sont ignorées une fois le délai d'attente écoulé.
  • Les messages sont uniquement au format JSON, limités à 64 Ko et analysés exactement une fois de chaque côté.
  • Les changements répétés de titre et de badge sont annulés ; la dernière valeur valide gagne.
  • __receive est uniquement implémenté, non énumérable lorsque cela est possible et rejette les messages en dehors du schéma.
Règles de sécurité

Le pont est étroit de par sa conception.

Un pont WebView crée une autorité native dans le contenu Web, de sorte que le shell de l'application traite chaque message de page comme une entrée non fiable, même lorsque la page vous appartient. Il applique ces règles :

1

Le pont est activé uniquement sur les origines HTTPS exactes et les modèles d'URL configurés pour votre application, et désactivé avant de naviguer ailleurs.

2

Les types de messages sont inscrits sur liste verte et chaque charge utile est validée par rapport au schéma de protocole négocié. Les champs inconnus sont ignorés et les commandes inconnues rejetées.

3

Les informations d'identification du magasin, les jetons push, les identifiants d'appareil, les cookies d'authentification et les chemins du système de fichiers natif ne sont jamais exposés au JavaScript de la page.

4

Seules les URL relatives ou les destinations HTTPS validées sont acceptées. javascript :, data :, file :, intent : et les schémas personnalisés sont bloqués à moins qu'une commande spécifique ne les mette sur liste blanche.

5

Les invites d'autorisation, les solutions de secours de partage, les liens de paramètres et les actions natives perturbatrices nécessitent un geste récent de l'utilisateur.

6

Les commandes sont limitées en débit, les messages sont limités à 64 Ko et les chaînes et les appels natifs ont des limites de longueur et des délais d'attente.

7

Les charges utiles sont supprimées des journaux de production. Les erreurs de diagnostic contiennent des codes et des identifiants de message, jamais de contenu client ou de secrets.

8

Les demandes de badges surveillés suivent les règles de récupération du navigateur. Les informations d’identification de même origine sont la valeur par défaut ; les URL d’origine croisée doivent passer CORS.

Avant de passer en direct

Testez votre intégration.

Le SDK modifie uniquement le comportement au sein de votre application. Vérifiez les deux chemins afin que les utilisateurs de l'application bénéficient de l'expérience native et que les visiteurs du navigateur continuent de fonctionner exactement comme avant.

  • Ouvrez les pages qui appellent le SDK dans un navigateur mobile normal et confirmez que rien ne se casse lorsque context.available est faux.
  • Testez dans l'application sur iOS et Android, y compris les réseaux lents, l'état hors ligne et la reprise après une longue période en arrière-plan.
  • Vérifiez les titres, les badges et la navigation active après les rechargements et les changements d'itinéraire côté client.
  • Pour les actions natives, testez les chemins de geste de l’utilisateur, d’autorisation refusée et non pris en charge.
  • Si votre site utilise une politique de sécurité du contenu, autorisez l'origine du script SDK.

Y a-t-il un cas d'utilisation qui manque à ce contrat ?

Partagez le flux du site Web, le comportement de l'application dont vous avez besoin et ce qui devrait se passer dans un navigateur normal. Cela nous suffit pour l’évaluer.

Envoyer un cas d'utilisation