Skip to content

Commit acc3b01

Browse files
authored
fix: defers page view actions to allow user context to be set first (formbricks#7048)
1 parent 3434b5c commit acc3b01

4 files changed

Lines changed: 18 additions & 10 deletions

File tree

packages/js-core/src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ const setup = async (setupConfig: TConfigInput): Promise<void> => {
3838

3939
// wait for setup to complete
4040
await queue.wait();
41+
42+
// Schedule checkPageUrl to run in the next event loop iteration.
43+
// This ensures that any user actions (like setUserId) called synchronously after setup()
44+
// will be queued BEFORE the page view actions are processed.
45+
setTimeout(() => {
46+
void checkPageUrl();
47+
}, 0);
4148
};
4249

4350
const setUserId = async (userId: string): Promise<void> => {

packages/js-core/src/lib/common/setup.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Logger } from "@/lib/common/logger";
66
import { getIsSetup, setIsSetup } from "@/lib/common/status";
77
import { filterSurveys, getIsDebug, isNowExpired, wrapThrows } from "@/lib/common/utils";
88
import { fetchEnvironmentState } from "@/lib/environment/state";
9-
import { checkPageUrl } from "@/lib/survey/no-code-action";
109
import { closeSurvey } from "@/lib/survey/widget";
1110
import { DEFAULT_USER_STATE_NO_USER_ID } from "@/lib/user/state";
1211
import { sendUpdatesToBackend } from "@/lib/user/update";
@@ -320,8 +319,6 @@ export const setup = async (
320319
setIsSetup(true);
321320
logger.debug("Set up complete");
322321

323-
// check page url if set up after page load
324-
void checkPageUrl();
325322
return okVoid();
326323
};
327324

packages/js-core/src/lib/common/tests/setup.test.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ describe("setup.ts", () => {
243243
},
244244
filteredSurveys: [{ name: "SurveyA" }],
245245
});
246-
expect(vi.mocked(await import("@/lib/survey/no-code-action")).checkPageUrl).toHaveBeenCalled();
247246
});
248247

249248
test("calls handleErrorOnFirstSetup if environment fetch fails initially", async () => {
@@ -318,11 +317,6 @@ describe("setup.ts", () => {
318317
await handleErrorOnFirstSetup(errorObj);
319318
}).rejects.toThrow("Could not set up formbricks");
320319

321-
// expect(AsyncStorage.setItem).toHaveBeenCalledWith(
322-
// RN_ASYNC_STORAGE_KEY,
323-
// expect.stringContaining('"value":"error"')
324-
// );
325-
326320
expect(setItemMock).toHaveBeenCalledWith(
327321
JS_LOCAL_STORAGE_KEY,
328322
expect.stringContaining('"value":"error"')

packages/js-core/src/lib/user/update-queue.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ export class UpdateQueue {
118118

119119
// Only send updates if we have a userId (either from updates or local storage)
120120
if (effectiveUserId) {
121+
const previousUserId = config.get().user.data.userId;
122+
const isNewUser = currentUpdates.userId && currentUpdates.userId !== previousUserId;
123+
const hasAttributes = Object.keys(currentUpdates.attributes ?? {}).length > 0;
124+
121125
const result = await sendUpdates({
122126
updates: {
123127
userId: effectiveUserId,
@@ -126,7 +130,13 @@ export class UpdateQueue {
126130
});
127131

128132
if (result.ok) {
129-
logger.debug("Updates sent successfully");
133+
if (isNewUser) {
134+
logger.debug(`User successfully identified: ${effectiveUserId}`);
135+
}
136+
if (hasAttributes) {
137+
const attributeKeys = Object.keys(currentUpdates.attributes ?? {}).join(", ");
138+
logger.debug(`Attributes successfully set: ${attributeKeys}`);
139+
}
130140
} else {
131141
logger.error(
132142
`Failed to send updates: ${result.error.responseMessage ?? result.error.message}`

0 commit comments

Comments
 (0)