From 2b7752b029a0a22bf0277937e106237052cbc0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E6=98=9F?= Date: Tue, 10 Mar 2026 19:15:52 +0800 Subject: [PATCH] fix: add forceNew option to bypass singleton for SSR SSR in production persists module-level singleton across requests, causing stale bootstrap data. forceNew skips the cache and creates a fresh client instance without polluting the singleton. Co-Authored-By: Claude Opus 4.6 --- src/statsig/client.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/statsig/client.ts b/src/statsig/client.ts index f6c72b4..eb02d68 100644 --- a/src/statsig/client.ts +++ b/src/statsig/client.ts @@ -40,6 +40,12 @@ export interface InitOptions extends StatsigOptions { * The data will be set before initializeSync() is called. */ bootstrap?: StatsigBootstrap | null; + + /** + * Skip singleton cache and create a new client instance. + * Use this for SSR where each request needs its own client with fresh bootstrap data. + */ + forceNew?: boolean; } /** @@ -65,9 +71,9 @@ export function initStatsigClient( user: StatsigUser, options?: InitOptions, ): StatsigClient { - if (client) return client; + const { isTestEnv, logger, bootstrap, forceNew, ...statsigOptions } = options ?? {}; - const { isTestEnv, logger, bootstrap, ...statsigOptions } = options ?? {}; + if (!forceNew && client) return client; // Set custom logger if (logger) { @@ -91,15 +97,20 @@ export function initStatsigClient( log(`Initializing in default mode (userID: '${user.userID}')`); } - client = new StatsigClient(clientKey, user, statsigOptions); + const instance = new StatsigClient(clientKey, user, statsigOptions); // Set bootstrap data before initializeSync (enables zero-network init) if (bootstrap?.data) { - client.dataAdapter.setData(bootstrap.data); + instance.dataAdapter.setData(bootstrap.data); } - client.initializeSync(); - return client; + instance.initializeSync(); + + if (!forceNew) { + client = instance; + } + + return instance; } /**