From 9c7e551d2f52ad01b59da9163d1e8b09c70dddfd Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Wed, 6 Nov 2024 12:05:36 +0200 Subject: [PATCH 1/2] fix(clerk-js): Init options on updateProps We need to re-init the options during the updateProps() call in order to keep the options passed to ClerkProvider in sync with the state of clerk-js. If we don't init the options here again, the following scenario is possible: 1. User renders 2. clerk-js initializes propA with a default value 3. The customer update propB independently of propA and window.Clerk.updateProps is called 4. If we don't merge the new props with the current options, propA will be reset to undefined --- packages/clerk-js/src/core/clerk.ts | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 7c610a15d50..5cde53679bd 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -294,10 +294,7 @@ export class Clerk implements ClerkInterface { ); } - this.#options = { - ...defaultOptions, - ...options, - }; + this.#options = this.#initOptions(options); assertNoLegacyProp(this.#options); @@ -314,11 +311,6 @@ export class Clerk implements ClerkInterface { }); } - this.#options.allowedRedirectOrigins = createAllowedRedirectOrigins( - this.#options.allowedRedirectOrigins, - this.frontendApi, - ); - if (this.#options.standardBrowser) { this.#loaded = await this.#loadInStandardBrowser(); } else { @@ -1602,9 +1594,14 @@ export class Clerk implements ClerkInterface { this.#fapiClient.onAfterResponse(callback); }; - __unstable__updateProps = (props: any) => { - // The expect-error directive below is safe since `updateAppearanceProp` is only used - // in the v4 build. This will be removed when v4 becomes the main stable version + __unstable__updateProps = (_props: any) => { + // We need to re-init the options here in order to keep the options passed to ClerkProvider + // in sync with the state of clerk-js. If we don't init the options here again, the following scenario is possible: + // 1. User renders + // 2. clerk-js initializes propA with a default value + // 3. The customer update propB independently of propA and window.Clerk.updateProps is called + // 4. If we don't merge the new props with the current options, propA will be reset to undefined + const props = { ..._props, options: this.#initOptions({ ...this.#options, ..._props.options }) }; return this.#componentControls?.ensureMounted().then(controls => controls.updateProps(props)); }; @@ -1976,6 +1973,14 @@ export class Clerk implements ClerkInterface { return true; }; + #initOptions = (options?: ClerkOptions): ClerkOptions => { + return { + ...defaultOptions, + ...options, + allowedRedirectOrigins: createAllowedRedirectOrigins(options?.allowedRedirectOrigins, this.frontendApi), + }; + }; + /** * The handshake payload is transported in the URL in development. In cases where FAPI is returning the handshake payload, but Clerk is being used in a client-only application, * we remove the handshake associated parameters as they are not necessary. From 55eaf8ad9bc869b5abab14cc39880fe249bbbdf5 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Wed, 6 Nov 2024 12:12:09 +0200 Subject: [PATCH 2/2] Create nine-pets-rhyme.md --- .changeset/nine-pets-rhyme.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/nine-pets-rhyme.md diff --git a/.changeset/nine-pets-rhyme.md b/.changeset/nine-pets-rhyme.md new file mode 100644 index 00000000000..9c7d6fa174e --- /dev/null +++ b/.changeset/nine-pets-rhyme.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": patch +--- + +Re-init window.Clerk options when `ClerkProvider` props change in `@clerk/clerk-react`