@v-tilt/browser 1.4.3 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -380,17 +380,49 @@ class UserManager {
380
380
  // Storage Operations (using StorageManager)
381
381
  // ============================================================================
382
382
  /**
383
- * Load user identity from storage
383
+ * Load user identity from storage.
384
+ *
385
+ * For traditional SSR websites where each page navigation reloads JavaScript,
386
+ * identity MUST be persisted immediately when generated to ensure the same
387
+ * anonymous_id is used across all page loads.
388
+ *
389
+ * Flow:
390
+ * 1. Load from storage (reads cookies first for critical properties in SSR mode)
391
+ * 2. Generate new IDs if not found
392
+ * 3. Immediately persist to storage (saved to both localStorage and cookies)
393
+ *
394
+ * With `localStorage+cookie` persistence (default):
395
+ * - Critical properties are stored in cookies for SSR compatibility
396
+ * - Full data is stored in localStorage for fast SPA-style access
397
+ * - Cookies ensure identity persists across full page reloads
384
398
  */
385
399
  loadUserIdentity() {
386
- const anonymousId = this.storage.get(constants_1.ANONYMOUS_ID_KEY) || this.generateAnonymousId();
387
- const distinctId = this.storage.get(constants_1.DISTINCT_ID_KEY) || null;
388
- const deviceId = this.storage.get(constants_1.DEVICE_ID_KEY) || this.generateDeviceId();
400
+ // Try to load existing IDs from storage
401
+ // In localStorage+cookie mode, this reads from cookies first for critical properties
402
+ const storedAnonymousId = this.storage.get(constants_1.ANONYMOUS_ID_KEY);
403
+ const storedDeviceId = this.storage.get(constants_1.DEVICE_ID_KEY);
404
+ const storedDistinctId = this.storage.get(constants_1.DISTINCT_ID_KEY);
405
+ const storedUserState = this.storage.get(constants_1.USER_STATE_KEY);
389
406
  const properties = this.getStoredUserProperties();
390
- const userState = this.storage.get(constants_1.USER_STATE_KEY) ||
391
- "anonymous";
407
+ // Generate new IDs if not found in storage
408
+ const anonymousId = storedAnonymousId || this.generateAnonymousId();
409
+ const deviceId = storedDeviceId || this.generateDeviceId();
410
+ const distinctId = storedDistinctId || null;
411
+ const userState = storedUserState || "anonymous";
392
412
  // Ensure anonymous_id is never undefined
393
413
  const safeAnonymousId = anonymousId || this.generateAnonymousId();
414
+ // CRITICAL: Immediately persist newly generated IDs to storage
415
+ // This ensures identity survives page reloads in traditional SSR websites
416
+ // In localStorage+cookie mode, critical properties are saved to cookies automatically
417
+ if (!storedAnonymousId) {
418
+ this.storage.set(constants_1.ANONYMOUS_ID_KEY, safeAnonymousId, storage_1.USER_COOKIE_MAX_AGE);
419
+ }
420
+ if (!storedDeviceId) {
421
+ this.storage.set(constants_1.DEVICE_ID_KEY, deviceId, storage_1.USER_COOKIE_MAX_AGE);
422
+ }
423
+ if (!storedUserState) {
424
+ this.storage.set(constants_1.USER_STATE_KEY, userState, storage_1.USER_COOKIE_MAX_AGE);
425
+ }
394
426
  const identity = {
395
427
  distinct_id: distinctId,
396
428
  anonymous_id: safeAnonymousId,
package/lib/vtilt.js CHANGED
@@ -44,7 +44,10 @@ class VTilt {
44
44
  this.configManager = new config_1.ConfigManager(config);
45
45
  const fullConfig = this.configManager.getConfig();
46
46
  this.sessionManager = new session_1.SessionManager(fullConfig.storage || "cookie", fullConfig.cross_subdomain_cookie);
47
- this.userManager = new user_manager_1.UserManager(fullConfig.persistence || "localStorage", fullConfig.cross_subdomain_cookie);
47
+ // Default to localStorage+cookie for better SSR support (following PostHog)
48
+ // Critical properties (anonymous_id, device_id, etc.) are stored in cookies
49
+ // This ensures identity persists across page navigations in traditional SSR websites
50
+ this.userManager = new user_manager_1.UserManager(fullConfig.persistence || "localStorage+cookie", fullConfig.cross_subdomain_cookie);
48
51
  this.webVitalsManager = new web_vitals_1.WebVitalsManager(fullConfig, this);
49
52
  // Initialize rate limiter to prevent flooding
50
53
  // Default: 10 events/second with burst of 100
@@ -747,7 +750,8 @@ class VTilt {
747
750
  const fullConfig = this.configManager.getConfig();
748
751
  // Recreate managers with new config
749
752
  this.sessionManager = new session_1.SessionManager(fullConfig.storage || "cookie", fullConfig.cross_subdomain_cookie);
750
- this.userManager = new user_manager_1.UserManager(fullConfig.persistence || "localStorage", fullConfig.cross_subdomain_cookie);
753
+ // Default to localStorage+cookie for better SSR support (following PostHog)
754
+ this.userManager = new user_manager_1.UserManager(fullConfig.persistence || "localStorage+cookie", fullConfig.cross_subdomain_cookie);
751
755
  this.webVitalsManager = new web_vitals_1.WebVitalsManager(fullConfig, this);
752
756
  // Update session recording config if it exists
753
757
  if (this.sessionRecording && fullConfig.session_recording) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v-tilt/browser",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "description": "vTilt browser tracking library",
5
5
  "main": "dist/main.js",
6
6
  "module": "dist/module.js",