Une application Electron n'est pas une page web même si elle est faite à partir d'une : il n'y a donc pas de balise script ici : il y a un paquet et un appel par processus. Voir mesurer une application pour ce que cela vous apporte. Le paquet Electron de Skomi ne dépend de rien d'autre que d'Electron lui-même.
Le code source, et une application de démonstration qui se mesure elle-même, sont sur skomi-sdk-electron.
Trois processus, trois lignes
// main.js — démarrez-le une fois
const skomi = require('@skomi/electron').init({
appId: 'your-app-id',
});
skomi.screen('launch');
// preload.js — exposez-le à la fenêtre
require('@skomi/electron/preload');
// renderer — là où vit votre routage
window.skomi.screen('checkout/review', { tier: 'gold' });
C'est toute l'intégration. L'identifiant de l'application vient de My Apps dans Skomi. Ce n'est pas un secret et il a sa place dans votre code source : il identifie une application plutôt qu'il ne l'authentifie, comme le fait un identifiant de site.
⚠ N'allez pas chercher l'extrait web dans votre renderer. Il mesure un site : il lui faut un nom d'hôte, un document à surveiller et un réseau sur lequel il peut compter, et une fenêtre Electron n'a rien de tout cela de la façon qu'il attend. Le SDK existe parce que les problèmes d'une application de bureau sont d'un autre ordre.
Nommez vos écrans
Il n'y a pas de capture automatique, et c'est délibéré : un chemin de route est ce que votre code appelle un écran, pas ce que vous appelleriez ainsi dans un rapport. Jusqu'à 20 propriétés par écran : chaînes, nombres ou booléens.
Ce que le SDK prend en charge et qu'il vous faudrait écrire autrement
Il fonctionne hors ligne. Les écrans sont mis en file sur le disque, dans le répertoire de données propre à l'application, et survivent à la fermeture, au plantage et à quinze jours sans réseau. Une application de bureau qui ne rapporterait qu'en ligne perdrait précisément les sessions qui comptent.
Il ne compte pas deux fois. Chaque écran porte un identifiant émis une fois et renvoyé inchangé : un lot réessayé est donc reconnu plutôt que compté de nouveau. Une file hors ligne sans cela transforme ce qui sauve vos données en ce qui les invente.
Il survit à une horloge fausse. Chaque lot enregistre le moment où il a été vidé, si bien que le serveur peut calculer de combien l'horloge de la machine est décalée et corriger le lot. Un portable réglé sur mardi prochain rapporterait sinon mardi prochain.
Il ne lève jamais d'exception dans votre code. Mauvais arguments, serveur injoignable, répertoire de profil non inscriptible, tout est traité en interne et rapporté via onError si vous voulez le savoir. L'analytics est la chose la moins importante que fait votre application.
Attendre le consentement
const skomi = require('@skomi/electron').init({ appId: '…', enabled: false });
// plus tard, une fois que l'utilisateur a donné son accord
skomi.setEnabled(true);
Rien n'est enregistré tant que c'est désactivé, pas même mis en file pour plus tard. Un écran vu avant que quelqu'un ne donne son accord n'est pas un écran que vous devriez envoyer après coup.
Erreurs et plantages
skomi.captureError(err, { screenName: 'checkout', fatal: false });
Mis en file, persistés et réessayés comme un écran, et dédoublonnés par la même règle, ce qui importe davantage ici, parce qu'un plantage est le plus souvent envoyé depuis la file au lancement suivant.
⚠ captureUncaught est désactivé par défaut, et réfléchissez avant de l'activer. Attacher un écouteur à uncaughtException est précisément ce qui empêche Node de s'arrêter : un rapporteur de plantages installé par défaut transformerait donc un plantage fatal en un processus qui continue de tourner sur un état corrompu. Avec le drapeau activé, la sémantique est rétablie : le rapport est écrit sur le disque de façon synchrone, l'écouteur est retiré, et l'erreur est levée de nouveau.
Options
init({
appId: '…', // requis
appVersion: app.getVersion(), // par défaut : demandé à Electron
origin: 'https://t.skomi.com', // à surcharger pour l'auto-hébergement
enabled: true, // démarrez à false, activez après consentement
flushIntervalMs: 10000,
onError(error, context) { }, // 'screen' | 'flush' | 'transport' | 'rejected' | 'queue'
});
init câble le canal du renderer et vide la file à la fermeture. Si vous voulez un client dont vous maîtrisez la durée de vie (pas d'IPC, pas de crochet de fermeture), utilisez createClient à la place.
Ce qu'une application n'obtient pas
⚠ Seule l'analytics lit une application. Les cartes de chaleur, les enregistrements de session et le widget de retours sont des produits pour sites : il leur faut une page dans un navigateur, et il n'y a rien à quoi s'accrocher dans une fenêtre de bureau. Une application rapporte des écrans, des sessions, des versions, des plateformes et des erreurs, et c'est tout.
Voir mesurer une application pour ce que le tableau de bord en fait, et installation dans MAUI ou Flutter si vous livrez aussi le même produit là.