ChemPal Documentation - v1.17.0
    Preparing search index...

    Function getFingerprintDistinctId

    • Computes the device-fingerprint distinct_id: a hash of a handful of highly stable navigator signals, readable identically in the popup, options page, and the service worker (no screen/DOM dependency). Because it's a pure function of the environment rather than something stored, the same physical install produces the same id before and after a reinstall — chrome.storage.local (where the old random id lived) can be wiped with no effect on it.

      This is a coarse cohort identifier, not a strong unique-device id — deliberately low entropy. Signals were chosen to exclude anything volatile (the UA version string, which churns roughly every 4 weeks on auto-update; Intl timezone or navigator.languages, which drift without any user action) since either would fragment the id and defeat "stable across reinstall." That leaves common, stable traits — many unrelated installs sharing typical hardware (e.g. "8 cores, Win32, en-US") will hash to the same id, so PostHog will under-count unique installs, not over-count. Higher-entropy techniques (canvas/WebGL/audio fingerprinting) would fix that but are the specific pattern Chrome Web Store review and privacy tooling scrutinize, and were deliberately ruled out, not just downweighted.

      Returns string

      The fp_-prefixed fingerprint id. Falls back to a fresh, non-cached crypto.randomUUID() for this call only if reading navigator somehow throws.

      getFingerprintDistinctId(); // => "fp_3f9c2a1b..." — stable for this device
      
      export function getFingerprintDistinctId(): string {
      if (cachedFingerprint) return cachedFingerprint;

      try {
      const nav = navigator as NavigatorWithFingerprintSignals;
      const signals = {
      fpVersion: FINGERPRINT_VERSION,
      platform: nav.userAgentData?.platform ?? nav.platform ?? '',
      mobile: nav.userAgentData?.mobile ?? false,
      cores: nav.hardwareConcurrency ?? 0,
      memory: nav.deviceMemory ?? 0,
      lang: nav.language ?? '',
      };
      cachedFingerprint = `fp_${md5(JSON.stringify(signals))}`;
      return cachedFingerprint;
      } catch {
      return crypto.randomUUID();
      }
      }