Wrapply logoTutoriels Wrapply
🧩 Bridge natif

API Bridge Wrapply : connecter le site aux fonctions natives

Guide pratique des API bridge natives Wrapply pour notifications, deeplinks, liens entrants, achats in-app et localisation dans les apps Flutter générées.

Référence Native Bridge

L’app Flutter générée expose window.Wrapply dans la WebView. Votre site peut appeler cet objet pour utiliser les fonctions natives uniquement si le module correspondant est activé. Attendez toujours wrapplyNativeBridgeReady et gérez toujours { ok:false, error } comme un cas normal de fallback.

APIQuand l’utiliserEntréeRéponse
window.Wrapply.isNativeApp()Détecte le wrapper natifnonetrue inside app
notifications.requestPermission(payload)Demande l’autorisation de notifications{ provider }{ ok, permission, granted }
notifications.getToken(payload)Lit ou rafraîchit le token appareil{ provider, refresh? }{ ok, token, provider }
notifications.refreshToken(payload)Régénère le token. Alias : updateToken{ provider }{ ok, token, refreshed:true }
notifications.show(payload)Affiche une notification locale immédiate{ title, body?, data? }{ ok, shown:true }
notifications.getStatus(payload)Lit l’état fournisseur et permissions{ provider }{ ok, granted, configured? }
iap.getProducts(payload)Lit les produits configurés dans le store{ packageName, productIds }{ ok, available, products }
iap.purchase(payload)Démarre un achat in-app{ packageName, productId, consumable? }{ ok, purchaseStarted }
iap.restorePurchases(payload)Restaure les achats non consommables{ packageName }{ ok, latestPurchases }
deepLinks.open(payload)Ouvre URL interne, externe, téléphone, email ou WhatsApp{ type, url/value }{ ok, type, url }
wrapply://open/pathOuvre l’app installée depuis email, SMS ou site externeexternal linkloads https://DOMAIN/path
Quand les fonctions bridge sont activées, Wrapply fournit aussi un PDF avec modules actifs, appels exacts, configuration fournisseur et notes pour la revue des stores.

Fournisseurs de notifications

Le site peut choisir le fournisseur de notifications à chaque appel. Wrapply inclut uniquement le fournisseur sélectionné dans l’app générée.

FournisseurUsageConfiguration requiseNote importante
localDéfaut sûr, token local stocké en shared preferencesAucun fichier externeUtile pour test/session ; pas un vrai token push distant
firebaseFournisseur Firebase Cloud Messagingandroid/app/google-services.json et optionnel ios/Runner/GoogleService-Info.plistSi les fichiers manquent, retour ok:false/configured:false
onesignalFournisseur OneSignalOneSignal App ID dans configuration/buildNécessite la configuration OneSignal avant les push distantes

Autorisations appareil

Caméra, microphone et géolocalisation utilisent les APIs web standard. Le wrapper ajoute les permissions natives Android/iOS lorsque la fonction est active.

FonctionAPI webPermissions nativesComportement
Caméranavigator.mediaDevices.getUserMedia({ video:true })Android CAMERA, iOS NSCameraUsageDescriptionUtilise l’API web standard ; l’app gère le prompt natif
Microphonenavigator.mediaDevices.getUserMedia({ audio:true })Android RECORD_AUDIO, iOS NSMicrophoneUsageDescriptionUtilise l’API web standard ; pas d’appel Wrapply direct
Géolocalisationnavigator.geolocation.getCurrentPosition(...)Android COARSE/FINE, texte iOS location usageLa position précise est optionnelle et doit être activée seulement si nécessaire

Exemples par type de code

Ces exemples sont volontairement courts : ils montrent le bon modèle d’intégration, tandis que le PDF généré liste les modules activés pour l’app.

Ready helper

function onWrapplyReady(callback) {
if (window.Wrapply && window.Wrapply.__nativeBridgeReady) {
callback(window.Wrapply);
return;
}
window.addEventListener("wrapplyNativeBridgeReady", () => {
callback(window.Wrapply);
}, { once: true });
}

JavaScript

document.querySelector("#notify").addEventListener("click", async () => {
if (!window.Wrapply?.notifications) return alert("Available inside the app");
const permission = await window.Wrapply.notifications.requestPermission({ provider: "firebase" });
if (!permission.ok || !permission.granted) return;
const token = await window.Wrapply.notifications.getToken({ provider: "firebase" });
await fetch("/api/device-token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: token.token, platform: "wrapply" })
});
});

TypeScript

type WrapplyResponse = Promise<Record<string, unknown>>;
declare global {
interface Window {
Wrapply?: {
__nativeBridgeReady?: boolean;
isNativeApp: () => Promise<boolean>;
notifications?: {
requestPermission: (p: Record<string, unknown>) => WrapplyResponse;
getToken: (p: Record<string, unknown>) => WrapplyResponse;
refreshToken: (p: Record<string, unknown>) => WrapplyResponse;
updateToken: (p: Record<string, unknown>) => WrapplyResponse;
show: (p: Record<string, unknown>) => WrapplyResponse;
getStatus: (p: Record<string, unknown>) => WrapplyResponse;
};
iap?: { purchase: (p: Record<string, unknown>) => WrapplyResponse };
deepLinks?: { open: (p: Record<string, unknown>) => WrapplyResponse };
};
}
}
export {};

React

import { useEffect, useState } from "react";
export function useWrapplyBridge() {
const [ready, setReady] = useState(false);
useEffect(() => {
if (window.Wrapply?.__nativeBridgeReady) return setReady(true);
const onReady = () => setReady(true);
window.addEventListener("wrapplyNativeBridgeReady", onReady);
return () => window.removeEventListener("wrapplyNativeBridgeReady", onReady);
}, []);
return { ready, Wrapply: ready ? window.Wrapply : null };
}

Vue 3

import { ref, onMounted, onBeforeUnmount } from "vue";
export function useWrapplyBridge() {
const ready = ref(false);
const markReady = () => { ready.value = true; };
onMounted(() => {
if (window.Wrapply?.__nativeBridgeReady) markReady();
else window.addEventListener("wrapplyNativeBridgeReady", markReady);
});
onBeforeUnmount(() => window.removeEventListener("wrapplyNativeBridgeReady", markReady));
return { ready };
}

Angular

@Injectable({ providedIn: "root" })
export class WrapplyBridgeService {
async requestToken(provider = "firebase") {
if (!window.Wrapply?.notifications) {
return { ok: false, error: "Bridge unavailable" };
}
return window.Wrapply.notifications.getToken({ provider });
}
}

jQuery

$("#wrapply-token").on("click", async function () {
if (!window.Wrapply?.notifications) return;
const result = await window.Wrapply.notifications.getToken({ provider: "local" });
$("#wrapply-output").text(JSON.stringify(result, null, 2));
});

PHP / Laravel Blade

<button onclick="buyNativeProduct()">Buy premium</button>
<script>
async function buyNativeProduct() {
if (!window.Wrapply?.iap) return;
const result = await window.Wrapply.iap.purchase({
packageName: "{{ config('app.mobile_package') }}",
productId: "premium_monthly",
consumable: false
});
console.log(result);
}
</script>

WordPress

add_action('wp_footer', function () { ?>
<script>
window.wrapplyNotify = async function () {
if (!window.Wrapply?.notifications) return;
return window.Wrapply.notifications.show({
title: "WordPress",
body: "Notification called from theme/plugin"
});
};
</script>
<?php });

Deep links

// External links from email, SMS, CRM or website
wrapply://open/profile
wrapply://open/checkout?plan=premium
wrapply://open/orders/123

// Native action inside the app
await window.Wrapply.deepLinks.open({ type: "internal_url", url: "https://example.com/account" });
await window.Wrapply.deepLinks.open({ type: "mailto", value: "support@example.com" });
await window.Wrapply.deepLinks.open({ type: "tel", value: "+390000000000" });
await window.Wrapply.deepLinks.open({ type: "whatsapp", value: "+390000000000" });

À quoi sert le bridge Wrapply

Le bridge expose une API JavaScript dans la WebView. Votre site peut appeler window.Wrapply et l’app Flutter exécute l’action native seulement si la fonctionnalité a été activée.

Avec les fonctions bridge, Wrapply fournit aussi un PDF avec les appels exacts, modules activés et notes de configuration.

Activez seulement les modules nécessaires

Notifications
Local/Firebase/OneSignal provider, permission request, token read/refresh and local notification display.
Actions and deeplinks
Open internal WebView URLs, external browser URLs, phone, email and WhatsApp from your website.
Inbound links
Open the installed app from a configured scheme or app link, then route the user to the right page.
In-app purchases
Query store products, start purchase, restore purchases and send results to your backend for validation.
Location
Add the native permission base for maps, nearby results or geolocation flows.

Setup flow

1. Configure features

Enable only the modules you need in the Wrapply configurator.

2. Add required files

Upload Firebase files or provider identifiers when the selected provider requires them.

3. Generate source code

Wrapply writes conditional dependencies, AndroidManifest entries, Info.plist keys and bridge modules.

4. Add JavaScript calls

Call window.Wrapply from your website only after checking the bridge exists.

5. Test before publishing

Test native permissions, tokens, purchases and links on real Android/iOS devices.

Exemples JavaScript réels

Use these calls from your website only after verifying that window.Wrapply exists.

Notifications

async function enablePush() {
if (!window.Wrapply?.notifications) return;
await window.Wrapply.notifications.requestPermission({ provider: 'firebase' });
const token = await window.Wrapply.notifications.getToken({ provider: 'firebase' });
await fetch('/api/device-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token.token, platform: 'app' })
});
}
window.Wrapply?.notifications?.show({ title: 'Order updated', body: 'Your request is ready' });

Actions and deeplinks

window.Wrapply?.deepLinks?.open({ type: 'internal_url', url: 'https://example.com/account' });
window.Wrapply?.deepLinks?.open({ type: 'mailto', value: 'support@example.com' });
window.Wrapply?.deepLinks?.open({ type: 'tel', value: '+390000000000' });
window.Wrapply?.deepLinks?.open({ type: 'whatsapp', value: '+390000000000' });
window.Wrapply?.deepLinks?.open({ type: 'url', url: 'https://example.com/help' });

In-app purchases

async function buyPremium() {
if (!window.Wrapply?.iap) return;
await window.Wrapply.iap.getProducts({ productIds: ['premium_monthly'] });
const result = await window.Wrapply.iap.purchase({
productId: 'premium_monthly',
consumable: false,
applicationUserName: currentUser.id
});
await fetch('/api/iap/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result)
});
}

Location

if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
console.log(position.coords.latitude, position.coords.longitude);
});
}

Ce que vous recevez

Conditional source code
Only selected dependencies, permissions and bridge files are included.
Configuration files
Firebase files, OneSignal App ID and iOS optional files are inserted only when requested.
PDF implementation guide
Avec les fonctions bridge, Wrapply fournit aussi un PDF avec les appels exacts, modules activés et notes de configuration.
Store review support
Payment, notification and permission modules should be tested before publishing.

FAQ bridge

Does the bridge work on the public website?

No. It works inside the generated app WebView. Always check window.Wrapply before calling native APIs.

Do I need a backend?

For Firebase push and in-app purchase validation, yes. The app exposes tokens and purchase events, but the backend should send messages and validate receipts.

Can Wrapply implement it?

Yes. Managed publishing can include configuration, testing and documentation for the enabled bridge modules.

Ready to connect native features?

Guide pratique des API bridge natives Wrapply pour notifications, deeplinks, liens entrants, achats in-app et localisation dans les apps Flutter générées.