Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nine-pets-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/clerk-js": patch
---

Re-init window.Clerk options when `ClerkProvider` props change in `@clerk/clerk-react`
29 changes: 17 additions & 12 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,7 @@ export class Clerk implements ClerkInterface {
);
}

this.#options = {
...defaultOptions,
...options,
};
this.#options = this.#initOptions(options);

assertNoLegacyProp(this.#options);

Expand All @@ -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 {
Expand Down Expand Up @@ -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 <ClerkProvider propA={undefined} propB={1} />
// 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));
};

Expand Down Expand Up @@ -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.
Expand Down