LOVABLE · BOLT · BASE44 → FONCTIONS NATIVES

Fonctions natives pour les apps Lovable, Bolt et Base44 : les prompts à coller

Votre app SaasToStore affiche votre site en ligne. Dans l'app, votre site peut aussi ouvrir le menu de partage du téléphone, le faire vibrer, scanner un QR code et programmer des rappels, sur Android et iOS. Vous n'écrivez pas ce code : copiez un des prompts ci-dessous, collez-le dans le chat de Lovable, Bolt ou Base44, et l'IA ajoute la fonction à votre site. Dans un navigateur normal, votre site continue de marcher comme aujourd'hui.

Mis à jour le 3 novembre 2026

Avant de coller un prompt

Chaque fonction est un plugin de votre projet SaasToStore. Le prompt modifie votre site ; le plugin met la fonction dans l'app.

  • Ajoutez le plugin, puis lancez un nouveau build

    Ouvrez la bibliothèque de plugins de votre projet, ajoutez le plugin, puis lancez un nouveau build : une app construite avant l'ajout n'a pas la fonction. Les plugins marchent dans les builds Android natifs (Android Build (Native), Android TV) et dans les apps iOS. Ils ne sont ni dans l'Android Build (Web) (TWA), ni dans le build d'essai gratuit, qui montre votre site en app, sans plugins.

  • Testez dans l'app, pas dans l'aperçu de l'éditeur

    L'aperçu de Lovable, Bolt et Base44 affiche votre site dans un cadre de l'éditeur, et les plugins ne tournent que dans votre app, jamais dans un cadre. Il ne s'y passe donc rien, et c'est normal : les prompts gardent votre site fonctionnel sans eux. Publiez votre site, puis ouvrez votre app sur un téléphone.

  • Votre site change, l'app suit

    L'app charge votre site publié. Une fois le plugin dans l'app, une modification publiée dans Lovable, Bolt ou Base44 arrive dans l'app sans nouveau build.

Où coller le prompt

Chaque prompt se suffit à lui-même : collez-en un à la fois, vérifiez le résultat, puis passez au suivant. L'IA adapte les noms de fichiers à votre projet.

  • Lovable

    Collez-le dans le chat de votre projet. Une fois la modification faite, cliquez sur Publish : l'app charge votre site publié, pas l'aperçu.

  • Bolt

    Collez-le dans le chat de Bolt, puis redéployez, avec le bouton de déploiement de Bolt ou chez votre hébergeur. L'app charge l'adresse déployée.

  • Base44

    Collez-le dans le chat IA de votre app, puis publiez. L'app charge l'adresse publique de votre app.

Partage natif

Un bouton Partager qui ouvre le menu de partage du téléphone : messages, e-mail, réseaux sociaux. Du texte et des liens seulement, pas de fichiers. Aucune autorisation, aucune fenêtre pour la personne.

Prompt · partage natif

Ajoute à mon projet un bouton de partage natif, avec le pont d'app SaasToStore.

Contexte : mon site tourne aussi dans une app mobile native construite avec SaasToStore. Dans cette app, la fonction `window.saastostore.share` ouvre le menu de partage du téléphone. Dans un navigateur normal, et dans l'aperçu de l'éditeur, il n'existe pas, et le site doit continuer à fonctionner exactement comme aujourd'hui. Ne modifie rien d'autre.

1. Si mon projet n'a pas encore de `src/lib/saastostore.ts`, crée-le (`.js` si mon projet n'utilise pas TypeScript) ; s'il existe, ajoute seulement ce qui manque :
   - `isInApp()` : renvoie `typeof window !== "undefined" && navigator.userAgent.includes("SaasToStoreApp")`.
   - `bridge()` : renvoie `typeof window !== "undefined" ? window.saastostore : undefined`. Ne lis jamais `window.saastostore` pendant le rendu serveur.
   - le type TypeScript de `window.saastostore` (optionnel), avec ce membre optionnel :
     `share?: (o?: { title?: string; text?: string; url?: string }) => Promise<{ shared: boolean; error?: string } | null>`

2. Sur [LA PAGE OU L'ÉLÉMENT À PARTAGER], ajoute un bouton « Partager ». Quand on appuie dessus :
   - si `bridge()?.share` existe, appelle `bridge().share({ title: [TITRE], text: [TEXTE COURT], url: [LIEN COMPLET VERS LA PAGE] })`. `share` est une fonction, pas un objet. `url` doit commencer par `https://` ou `http://`. Sa promesse ne rejette jamais : si le résultat contient une `error`, affiche un court message.
   - sinon, si `navigator.share` existe, appelle `navigator.share({ title, text, url })` et ignore l'erreur levée quand la personne ferme le menu.
   - sinon, copie le lien dans le presse-papiers et affiche « Lien copié ».

3. `shared: true` veut seulement dire que le menu de partage s'est ouvert, pas que quelque chose a été envoyé : n'affiche pas de confirmation « Partagé ».

Remplacez les valeurs entre [CROCHETS] avant de coller. Ajoutez le plugin dans votre projet, puis lancez un nouveau build.

Retour haptique

De courtes vibrations qui confirment un appui, une réussite ou une erreur. Aucune fenêtre d'autorisation. Ce que la personne ressent dépend de son téléphone et de son réglage de vibrations ; sur Android, un appareil qui ne peut pas vibrer (la plupart des tablettes et des TV) ne fait rien.

Prompt · retour haptique

Ajoute un retour haptique à mon projet, avec le pont d'app SaasToStore.

Contexte : mon site tourne aussi dans une app mobile native construite avec SaasToStore. Dans cette app, `window.saastostore.haptics` fait vibrer brièvement le téléphone. Dans un navigateur normal, et dans l'aperçu de l'éditeur, il n'existe pas, et le site doit continuer à fonctionner exactement comme aujourd'hui. Ne modifie rien d'autre.

1. Si mon projet n'a pas encore de `src/lib/saastostore.ts`, crée-le (`.js` si mon projet n'utilise pas TypeScript) ; s'il existe, ajoute seulement ce qui manque :
   - `isInApp()` : renvoie `typeof window !== "undefined" && navigator.userAgent.includes("SaasToStoreApp")`.
   - `bridge()` : renvoie `typeof window !== "undefined" ? window.saastostore : undefined`. Ne lis jamais `window.saastostore` pendant le rendu serveur.
   - le type TypeScript de `window.saastostore` (optionnel), avec ce membre optionnel :
     `haptics?: { impact(o?: { style?: "light" | "medium" | "heavy" }): Promise<{ ok: boolean; error?: string } | null>; notification(o?: { type?: "success" | "warning" | "error" }): Promise<{ ok: boolean; error?: string } | null>; selection(): Promise<{ ok: boolean; error?: string } | null> }`

2. Dans le même fichier, ajoute trois fonctions qui ne font rien hors de l'app et n'attendent jamais le résultat :
   - `tapFeedback()` : appelle `bridge()?.haptics?.impact({ style: "light" })`.
   - `successFeedback()` : appelle `bridge()?.haptics?.notification({ type: "success" })`.
   - `errorFeedback()` : appelle `bridge()?.haptics?.notification({ type: "error" })`.
   Leurs promesses ne rejettent jamais. Ignore un résultat avec `ok: false` (par exemple `not_available` sur un téléphone qui ne vibre pas) : ne le montre jamais à la personne.

3. Appelle `tapFeedback()` à chaque appui sur [MES BOUTONS PRINCIPAUX], `successFeedback()` quand [UN FORMULAIRE, PAR EXEMPLE LE PAIEMENT] réussit et `errorFeedback()` quand il échoue.

4. Ne fais pas vibrer au défilement, à chaque touche tapée, ni plusieurs fois de suite.

Remplacez les valeurs entre [CROCHETS] avant de coller. Ajoutez le plugin dans votre projet, puis lancez un nouveau build.

Scanner de QR code

Un bouton Scanner qui lit un QR code ou un code-barres avec l'appareil photo : un billet, un produit, un lien. Sur Android, le lecteur est celui de Google (services Google Play) et votre app ne demande aucune autorisation d'appareil photo ; les téléphones sans services Google Play, comme les Amazon Fire et les Huawei, ne l'ont pas. Sur iOS, l'app ouvre son propre lecteur et demande l'appareil photo la première fois. Essayez-le avec un vrai code sur un vrai téléphone avant de publier.

Prompt · scanner de QR code

Ajoute un scanner de QR code à mon projet, avec le pont d'app SaasToStore.

Contexte : mon site tourne aussi dans une app mobile native construite avec SaasToStore. Dans cette app, `window.saastostore.barcode` ouvre le lecteur de codes du téléphone. Dans un navigateur normal, et dans l'aperçu de l'éditeur, il n'existe pas, et le site doit continuer à fonctionner exactement comme aujourd'hui. Ne modifie rien d'autre.

1. Si mon projet n'a pas encore de `src/lib/saastostore.ts`, crée-le (`.js` si mon projet n'utilise pas TypeScript) ; s'il existe, ajoute seulement ce qui manque :
   - `isInApp()` : renvoie `typeof window !== "undefined" && navigator.userAgent.includes("SaasToStoreApp")`.
   - `bridge()` : renvoie `typeof window !== "undefined" ? window.saastostore : undefined`. Ne lis jamais `window.saastostore` pendant le rendu serveur.
   - le type TypeScript de `window.saastostore` (optionnel), avec ce membre optionnel :
     `barcode?: { isAvailable(): Promise<{ available: boolean; reason?: string } | null>; scan(o?: { formats?: string[]; prompt?: string }): Promise<{ scanned: true; value: string; format: string } | { scanned: false; error: string } | null> }`

2. Sur [LA PAGE OÙ L'ON SCANNE], affiche un bouton « Scanner un code » seulement si `isInApp()` vaut true et si `bridge()?.barcode?.isAvailable()` répond `available: true`. Sinon, garde la page telle qu'elle est aujourd'hui (par exemple un champ pour taper le code).

3. Quand on appuie sur le bouton, appelle `bridge().barcode.scan({ formats: ["qr"], prompt: "[TEXTE AU-DESSUS DU VISEUR, 200 CARACTÈRES MAX]" })`. Sa promesse ne rejette jamais :
   - `scanned: true` : utilise `value` pour [CE QU'IL FAUT FAIRE DU CODE, PAR EXEMPLE OUVRIR LE BILLET].
   - `error: "cancelled"` : ne fais rien, la personne a fermé le lecteur.
   - `error: "not_allowed"` (iOS, appareil photo refusé) : explique que l'appareil photo peut être autorisé dans les réglages du téléphone.
   - toute autre erreur : affiche un court message.

4. `value` est un texte de source inconnue : vérifie-le avant de t'en servir, ne l'insère jamais dans la page comme du HTML, et ne l'ouvre jamais comme un lien sans vérifier qu'il pointe vers [MON DOMAINE].

Remplacez les valeurs entre [CROCHETS] avant de coller. Ajoutez le plugin dans votre projet, puis lancez un nouveau build.

Notifications locales (rappels)

Un bouton Me le rappeler qui programme une notification sur le téléphone, affichée à l'heure choisie même quand l'app est fermée : un rendez-vous, une séance qui commence, un panier abandonné. Aucun serveur n'intervient : ce n'est pas du push, et cela ne peut pas toucher tous vos utilisateurs d'un coup. Android affiche le rappel à quelques minutes près ; iOS est à l'heure. Les rappels survivent à un redémarrage du téléphone. Limites : 64 rappels en attente, jusqu'à 366 jours à l'avance.

Prompt · notifications locales

Ajoute des rappels (notifications locales) à mon projet, avec le pont d'app SaasToStore.

Contexte : mon site tourne aussi dans une app mobile native construite avec SaasToStore. Dans cette app, `window.saastostore.localNotifications` programme des notifications sur le téléphone lui-même, sans serveur. Dans un navigateur normal, et dans l'aperçu de l'éditeur, il n'existe pas, et le site doit continuer à fonctionner exactement comme aujourd'hui. Ne modifie rien d'autre.

1. Si mon projet n'a pas encore de `src/lib/saastostore.ts`, crée-le (`.js` si mon projet n'utilise pas TypeScript) ; s'il existe, ajoute seulement ce qui manque :
   - `isInApp()` : renvoie `typeof window !== "undefined" && navigator.userAgent.includes("SaasToStoreApp")`.
   - `bridge()` : renvoie `typeof window !== "undefined" ? window.saastostore : undefined`. Ne lis jamais `window.saastostore` pendant le rendu serveur.
   - le type TypeScript de `window.saastostore` (optionnel), avec ce membre optionnel :
     `localNotifications?: { requestPermission(): Promise<{ granted: boolean; status: "granted" | "denied" | "prompt"; error?: string } | null>; schedule(o: { id?: number; title: string; body?: string; at?: number | string; in?: number; data?: object }): Promise<{ scheduled: true; id: number; at: number } | { scheduled: false; error: string; status?: string } | null>; cancel(o: { id: number }): Promise<{ ok: boolean; error?: string } | null>; getLastOpened(): Promise<{ notification: { id: number; title: string; body: string; at: number; data: object } | null } | null> }`

2. Sur [L'ÉLÉMENT QUI MÉRITE UN RAPPEL, PAR EXEMPLE UNE RÉSERVATION], affiche un bouton « Me le rappeler » seulement si `isInApp()` vaut true et si `bridge()?.localNotifications` existe.

3. Quand on appuie sur le bouton (jamais au chargement de la page) :
   - appelle d'abord `bridge().localNotifications.requestPermission()`. Si `granted` vaut false, explique que les notifications peuvent être autorisées dans les réglages du téléphone, et arrête-toi là.
   - appelle ensuite `bridge().localNotifications.schedule({ id: [UN NOMBRE PROPRE À CET ÉLÉMENT], title: [TITRE, 200 CARACTÈRES MAX], body: [TEXTE COURT], at: [L'HEURE, EN MILLISECONDES OU date.toISOString()], data: { [L'ID DE L'ÉLÉMENT] } })`. Affiche « Rappel programmé » quand `scheduled` vaut true, et un court message sinon.
   Ces promesses ne rejettent jamais.

4. Quand la personne appuie sur la notification, ouvre [LA PAGE DE L'ÉLÉMENT] avec l'id trouvé dans `data` :
   - écoute `window.addEventListener("s2s:localNotifications", (e) => …)` et agis quand `e.detail.type === "tap"`, avec `e.detail.data` ;
   - appelle aussi `bridge()?.localNotifications?.getLastOpened()` une fois au démarrage de l'app : si l'app était fermée, l'événement est parti avant que la page écoute. Il renvoie `{ notification }` une fois, puis `{ notification: null }`.

5. Quand l'élément est annulé ou que le rappel ne sert plus, appelle `bridge()?.localNotifications?.cancel({ id })`.

Remplacez les valeurs entre [CROCHETS] avant de coller. Ajoutez le plugin dans votre projet, puis lancez un nouveau build.

Vérifiez le résultat

  • Dans un navigateur normal : la page s'affiche et marche comme avant, sans bouton qui ne fait rien.
  • Dans votre app, construite après l'ajout du plugin : le bouton s'affiche et fait son travail.
  • Fermez le menu de partage ou le scanner sans rien choisir : aucun message d'erreur n'apparaît.
  • Refusez une fois l'autorisation (notifications ; appareil photo sur iOS) : la page dit quoi faire au lieu d'échouer sans rien dire.

Questions fréquentes

Le même prompt marche-t-il dans Lovable, Bolt et Base44 ?+

Oui. Chaque prompt décrit la modification, pas un outil : le même texte marche dans le chat de Lovable, Bolt et Base44, et dans les autres outils d'IA qui modifient le code de votre site. L'IA choisit les bons noms de fichiers pour votre projet.

Pourquoi rien ne se passe dans l'aperçu de l'éditeur ?+

L'aperçu affiche votre site dans un cadre de l'éditeur. Les plugins ne tournent que dans le cadre principal de votre app, jamais dans un cadre ni dans un navigateur : window.saastostore n'y existe pas. Les prompts gardent votre site fonctionnel sans lui. Pour essayer une fonction, publiez votre site et ouvrez votre app sur un téléphone.

Faut-il un nouveau build après avoir collé un prompt ?+

Seulement pour ajouter le plugin. Les plugins sont écrits dans l'app au moment du build : ajoutez le plugin dans la bibliothèque de plugins de votre projet, puis lancez un nouveau build. Ensuite, une modification publiée sur votre site arrive dans l'app sans nouveau build, car l'app charge votre site publié.

Ces plugins sont-ils inclus dans mon offre ?+

Les plugins standard sont inclus dans les offres payantes, sans licence par plugin : ajoutez-en autant que votre app en a besoin. Le build d'essai gratuit (Android, au logo SaasToStore) montre votre site en app, sans plugins.

Mon app va-t-elle demander de nouvelles autorisations ?+

Le partage natif et le retour haptique ne demandent rien. Le scanner de QR code demande l'appareil photo sur iOS, la première fois qu'il scanne ; sur Android, il utilise le lecteur de Google et ne demande rien. Les notifications locales demandent l'autorisation sur Android 13 et plus et sur iOS, quand votre site appelle requestPermission() depuis un bouton.

Puis-je envoyer une notification à tous mes utilisateurs ?+

Pas avec ces prompts. Une notification locale est programmée par votre page sur un seul téléphone, sans serveur. Un message envoyé depuis votre serveur à vos utilisateurs, c'est du push, un autre plugin.

Guides associés

Ajoutez la fonction à votre app

Collez l'URL de votre site, ajoutez les plugins dans votre projet, puis lancez le build. Votre site continue de marcher dans le navigateur.

Créer mon app