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.
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
src="https://cdn.siteto.app/sdk/v1/sitetoapp.min.js"
defer
></script>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.
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.
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 contexte | Valeur | Raison |
|---|---|---|
| disponible | booléen | Si un shell natif a effectué une poignée de main valide. |
| plate-forme | iOS | androïde | la toile | Le runtime actif ; jamais déduit de l'agent utilisateur. |
| appVersion | chaîne | nul | La version de l'application native installée, lorsqu'elle est disponible. |
| sdkVersion | chaîne | La version du SDK du site Web chargée. |
| protocolVersion | numéro | nul | Le contrat relais négocié avec l'application. |
| capacités | chaîne[] | Commandes prises en charge telles que navigation.badge ou share. |
| colorScheme | lumière | sombre | L'apparence native actuelle. |
| safeArea | haut, droite, bas, gauche | Encarts en pixels CSS pour des mises en page plein écran personnalisées. |
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.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.
// 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.
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
// 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é.
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();| Option | Défaut | Comportement |
|---|---|---|
| URL | requis | HTTPS ou URL relative renvoyant du JSON ou du texte brut. |
| jsonPath | aucun | Chemin de points tel que cart.item_count. Obligatoire lorsque JSON n’est pas lui-même la valeur du badge. |
| intervalle | désactivé | Intervalle d'interrogation en millisecondes, avec un minimum de 15 secondes. |
| refreshOn | prêt, reprenez | Toute combinaison de prêt, CV, focus et changement d'URL. |
| informations d'identification | même origine | Utilise le mode Récupérer les informations d'identification du navigateur. Les requêtes d’origine croisée nécessitent toujours CORS. |
| temps mort | 5000 | Temps de récupération maximum en millisecondes. |
| hideWhenZero | vrai | Masquez le badge lorsque le résultat mappé est 0, nul ou faux. |
| vicié | garder | Conserver 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:errorsans casser la page.
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.
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.
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.
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:resumeL'application est revenue au premier plan. Actualisez les données des pages sensibles au facteur temps et les badges surveillés.
app:pauseL'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:reselectL'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:openLe shell a reçu un lien profond de confiance que le routeur de pages doit gérer sans rechargement complet.
notification:openedL'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:changeLa 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:changeL’aspect clair ou sombre d’origine a changé. La charge utile inclut le nouveau jeu de couleurs.
sdk:errorUn observateur, une commande de pont ou une validation de message a échoué. Destiné aux diagnostics, pas à la journalisation sensible.
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êt | Résout avec available: false et platform: web après le délai d'attente. |
| page.setTitle | Met à jour document.title lorsque le document est activé ; rapports de livraison natifs faux. |
| badges et état de l'article | Ne pas récupérer ou restituer par défaut. Retour livré : faux sans jeter. |
| navigation.open | Utilise location.assign, location.replace ou window.open en fonction de la cible. |
| navigation.back | Utilise history.back lorsque l'historique du navigateur est disponible. |
| partager | Utilise navigator.share, puis le presse-papiers après un geste de l'utilisateur. |
| avis | Retours non pris en charge ; il ne remplace pas le système de notification du navigateur. |
| haptique | No-op sécurisé avec livré : faux. |
{ delivered: false, reason: 'not-in-app' }. Les arguments invalides et les refus natifs utilisent typé SiteToAppError codes.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.
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
{
"channel": "sitetoapp",
"protocolVersion": 1,
"id": "sta_01J8ZQ6JY1",
"type": "navigation.badge.set",
"payload": {
"itemId": "cart",
"value": 3
},
"timestamp": 1789584000000
}Reconnaissance de l'application
{
"channel": "sitetoapp",
"protocolVersion": 1,
"type": "response",
"replyTo": "sta_01J8ZQ6JY1",
"ok": true,
"payload": null
}Application vers le site Web
// 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.
__receiveest uniquement implémenté, non énumérable lorsque cela est possible et rejette les messages en dehors du schéma.
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 :
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.
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.
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.
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.
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.
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.
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.
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.
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.availableest 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.