Skip to content

Electron

Electron apps track like websites as long as the page has a real origin. A BrowserWindow loading a remote URL needs nothing special; a bundled app needs a custom protocol scheme, because file:// pages have no origin to trust.

If your BrowserWindow loads a real https:// URL (for example win.loadURL("https://myapp.com")), it works exactly like a normal web page. The page’s origin is https://myapp.com, which just needs to be a trusted domain like any other site. Nothing Electron-specific to configure.

Instead, register a standard, secure custom protocol scheme before the app is ready, and load your bundled app through it:

main.js
const { app, protocol, BrowserWindow } = require("electron");
protocol.registerSchemesAsPrivileged([
{
scheme: "app",
privileges: {
standard: true,
secure: true,
supportFetchAPI: true,
corsEnabled: true,
},
},
]);
app.whenReady().then(() => {
// ... register a protocol.handle("app", ...) that serves your bundled files ...
const win = new BrowserWindow({ /* ... */ });
win.loadURL("app://myapp/index.html");
});

A page served over app://myapp/... has a real, non-opaque origin: app://myapp. Add myapp as a trusted domain in the dashboard (single-label domains, like localhost, are allowed) and point the snippet at it:

<script src="https://cdn.analytics.canarycoders.es/lytics.js" data-domain="myapp" defer></script>

With that in place, /ingest, the widget, and the browser SDK all work exactly as they would on the web.

The @canarylytics/sdk client is isomorphic, so in Electron’s main process it behaves like any Node server calling /v1. There is no Origin header and no CORS check there (that only applies to browser reads), just a Bearer-authed request:

main.js
import { createClient } from "@canarylytics/sdk";
const lytics = createClient({ apiKey: process.env.CANARYLYTICS_KEY });
await lytics.events.track("app_launched", { version: app.getVersion() });