From 2ebe3cdfa265a262b66dbae7c2665d221668d2b9 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Thu, 30 Oct 2025 11:40:35 -0400
Subject: [PATCH 1/3] Display legal field only based on missing fields
---
packages/clerk-js/src/test/fixture-helpers.ts | 1 +
.../src/ui/components/SignUp/SignUpStart.tsx | 12 +++++++++++-
.../SignUp/__tests__/SignUpStart.test.tsx | 18 ++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/packages/clerk-js/src/test/fixture-helpers.ts b/packages/clerk-js/src/test/fixture-helpers.ts
index ad32d5c9d2d..7c5cedaf802 100644
--- a/packages/clerk-js/src/test/fixture-helpers.ts
+++ b/packages/clerk-js/src/test/fixture-helpers.ts
@@ -275,6 +275,7 @@ const createSignUpFixtureHelpers = (baseClient: ClientJSON) => {
status: 'missing_requirements',
legal_accepted_at: null,
missing_fields: ['legal_accepted'],
+ unverified_fields: [],
} as SignUpJSON;
};
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
index 20f4a4711cd..91746c0d34b 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
@@ -1,7 +1,7 @@
import { getAlternativePhoneCodeProviderData } from '@clerk/shared/alternativePhoneCode';
import { useClerk } from '@clerk/shared/react';
import type { PhoneCodeChannel, PhoneCodeChannelData, SignUpResource } from '@clerk/shared/types';
-import React from 'react';
+import React, { useMemo } from 'react';
import { isClerkAPIResponseError } from '@/index.headless';
import { Card } from '@/ui/elements/Card';
@@ -130,6 +130,15 @@ function SignUpStartInternal(): JSX.Element {
const isLegalConsentEnabled = userSettings.signUp.legal_consent_enabled;
const oidcPrompt = ctx.oidcPrompt;
+ const onlyLegalAcceptedMissing = useMemo(
+ () =>
+ signUp.missingFields &&
+ signUp.missingFields.length === 1 &&
+ signUp.missingFields[0] === 'legal_accepted' &&
+ signUp.unverifiedFields &&
+ signUp.unverifiedFields.length === 0,
+ [signUp.missingFields, signUp.unverifiedFields],
+ );
const fields = determineActiveFields({
attributes,
hasTicket: hasTicket || hasExistingSignUpWithTicket,
@@ -445,6 +454,7 @@ function SignUpStartInternal(): JSX.Element {
formState={formState}
canToggleEmailPhone={canToggleEmailPhone}
handleEmailPhoneToggle={handleChangeActive}
+ onlyLegalAcceptedMissing={onlyLegalAcceptedMissing}
/>
)}
diff --git a/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx b/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx
index ac433090735..85effdf1044 100644
--- a/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx
@@ -352,6 +352,24 @@ describe('SignUpStart', () => {
screen.getByText('Terms of Service');
screen.getByText('Privacy Policy');
});
+
+ it('displays legal consent only if included in missing fields without unverified fields', async () => {
+ const { wrapper } = await createFixtures(f => {
+ f.withEmailAddress({ required: true });
+ f.withPassword({ required: true });
+ f.startSignUpWithMissingLegalAccepted();
+ f.withLegalConsent();
+ f.withTermsPrivacyPolicyUrls({
+ privacyPolicy: 'https://clerk.dev/privacy',
+ termsOfService: 'https://clerk.dev/tos',
+ });
+ });
+ const { getByText, queryByText } = render(, { wrapper });
+ expect(getByText('Terms of Service')).toBeVisible();
+ expect(getByText('Privacy Policy')).toBeVisible();
+ expect(queryByText('Phone number')).not.toBeInTheDocument();
+ expect(queryByText('Password')).not.toBeInTheDocument();
+ });
});
describe('ticket flow', () => {
From 446e5e0f245b9c5c5ca06eb1a79b154908ef0d04 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Thu, 30 Oct 2025 11:49:57 -0400
Subject: [PATCH 2/3] Add changeset
---
.changeset/silly-zoos-decide.md | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .changeset/silly-zoos-decide.md
diff --git a/.changeset/silly-zoos-decide.md b/.changeset/silly-zoos-decide.md
new file mode 100644
index 00000000000..bf86778e106
--- /dev/null
+++ b/.changeset/silly-zoos-decide.md
@@ -0,0 +1,5 @@
+---
+'@clerk/clerk-js': patch
+---
+
+Fix sign-up to render legal consent only when required and with no unverified fields
From 50acac0e914ddf9c6199fa03426f0cb1b921c062 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Mon, 3 Nov 2025 11:07:06 -0300
Subject: [PATCH 3/3] Navigate to `/continue` route based on
`missing_requirements` status
---
.changeset/silly-zoos-decide.md | 4 +++-
packages/clerk-js/src/test/fixture-helpers.ts | 1 -
.../src/ui/components/SignUp/SignUpStart.tsx | 13 ++-----------
.../SignUp/__tests__/SignUpStart.test.tsx | 18 ------------------
4 files changed, 5 insertions(+), 31 deletions(-)
diff --git a/.changeset/silly-zoos-decide.md b/.changeset/silly-zoos-decide.md
index bf86778e106..fd73a871219 100644
--- a/.changeset/silly-zoos-decide.md
+++ b/.changeset/silly-zoos-decide.md
@@ -2,4 +2,6 @@
'@clerk/clerk-js': patch
---
-Fix sign-up to render legal consent only when required and with no unverified fields
+Navigates to `/sign-up/continue` on sign-up with `missing_requirements` status using `ticket` as strategy
+
+It fixes IdP-initiated flows with missing requirements such as accepting legal consent
diff --git a/packages/clerk-js/src/test/fixture-helpers.ts b/packages/clerk-js/src/test/fixture-helpers.ts
index 7c5cedaf802..ad32d5c9d2d 100644
--- a/packages/clerk-js/src/test/fixture-helpers.ts
+++ b/packages/clerk-js/src/test/fixture-helpers.ts
@@ -275,7 +275,6 @@ const createSignUpFixtureHelpers = (baseClient: ClientJSON) => {
status: 'missing_requirements',
legal_accepted_at: null,
missing_fields: ['legal_accepted'],
- unverified_fields: [],
} as SignUpJSON;
};
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
index 91746c0d34b..54a82cc5b6e 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
@@ -1,7 +1,7 @@
import { getAlternativePhoneCodeProviderData } from '@clerk/shared/alternativePhoneCode';
import { useClerk } from '@clerk/shared/react';
import type { PhoneCodeChannel, PhoneCodeChannelData, SignUpResource } from '@clerk/shared/types';
-import React, { useMemo } from 'react';
+import React from 'react';
import { isClerkAPIResponseError } from '@/index.headless';
import { Card } from '@/ui/elements/Card';
@@ -130,15 +130,6 @@ function SignUpStartInternal(): JSX.Element {
const isLegalConsentEnabled = userSettings.signUp.legal_consent_enabled;
const oidcPrompt = ctx.oidcPrompt;
- const onlyLegalAcceptedMissing = useMemo(
- () =>
- signUp.missingFields &&
- signUp.missingFields.length === 1 &&
- signUp.missingFields[0] === 'legal_accepted' &&
- signUp.unverifiedFields &&
- signUp.unverifiedFields.length === 0,
- [signUp.missingFields, signUp.unverifiedFields],
- );
const fields = determineActiveFields({
attributes,
hasTicket: hasTicket || hasExistingSignUpWithTicket,
@@ -173,6 +164,7 @@ function SignUpStartInternal(): JSX.Element {
redirectUrlComplete,
verifyEmailPath: 'verify-email-address',
verifyPhonePath: 'verify-phone-number',
+ continuePath: 'continue',
handleComplete: () => {
removeClerkQueryParam('__clerk_ticket');
removeClerkQueryParam('__clerk_invitation_token');
@@ -454,7 +446,6 @@ function SignUpStartInternal(): JSX.Element {
formState={formState}
canToggleEmailPhone={canToggleEmailPhone}
handleEmailPhoneToggle={handleChangeActive}
- onlyLegalAcceptedMissing={onlyLegalAcceptedMissing}
/>
)}
diff --git a/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx b/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx
index 85effdf1044..ac433090735 100644
--- a/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/__tests__/SignUpStart.test.tsx
@@ -352,24 +352,6 @@ describe('SignUpStart', () => {
screen.getByText('Terms of Service');
screen.getByText('Privacy Policy');
});
-
- it('displays legal consent only if included in missing fields without unverified fields', async () => {
- const { wrapper } = await createFixtures(f => {
- f.withEmailAddress({ required: true });
- f.withPassword({ required: true });
- f.startSignUpWithMissingLegalAccepted();
- f.withLegalConsent();
- f.withTermsPrivacyPolicyUrls({
- privacyPolicy: 'https://clerk.dev/privacy',
- termsOfService: 'https://clerk.dev/tos',
- });
- });
- const { getByText, queryByText } = render(, { wrapper });
- expect(getByText('Terms of Service')).toBeVisible();
- expect(getByText('Privacy Policy')).toBeVisible();
- expect(queryByText('Phone number')).not.toBeInTheDocument();
- expect(queryByText('Password')).not.toBeInTheDocument();
- });
});
describe('ticket flow', () => {