Skip to content

feat(ui,shared,localizations): provider selection step for <__experimental_ConfigureSSO />#8503

Open
iagodahlem wants to merge 16 commits into
mainfrom
iago/orgs-1462
Open

feat(ui,shared,localizations): provider selection step for <__experimental_ConfigureSSO />#8503
iagodahlem wants to merge 16 commits into
mainfrom
iago/orgs-1462

Conversation

@iagodahlem
Copy link
Copy Markdown
Member

@iagodahlem iagodahlem commented May 7, 2026

Summary

Implements the first wizard step of <__experimental_ConfigureSSO /> — the provider selection screen — and the state machine foundation that makes it work end-to-end. The user picks one of two SAML providers (Okta Workforce, Custom SAML Provider), Continue creates the enterprise connection, and the wizard advances. On reload, deriveInitialStep lands the user on the correct step based on the connection's state. All user-visible copy is wired through @clerk/localizations with translations for every supported locale. No public component API change.

Linear: ORGS-1462

Why

After the layered architecture landed in #8493, SelectProviderStep was registered as a regular <Wizard.Step> with a placeholder body. The step is structurally a wizard step (not a pre-wizard gate), but is filtered out of the breadcrumb in ConfigureSSOHeader by id so the visible step count stays at 4 (Verify domain → Configure → Test → Confirmation). This PR fills in the body with the real provider tiles, selection behavior, the localization plumbing — and the flow-context plumbing the rest of the wizard depends on. The createConnection call lands here as an interim location; a small follow-up will move it into Verify Domain's EnterVerificationCodeStep.onResolve once Laura's #8520 merges.

What changed

Select Provider step UI

  • steps/SelectProviderStep.tsx — replaces the placeholder body with:
    • Sub-header block (Select your identity provider + helper copy)
    • SAML group containing two equal-width tiles laid out via Grid columns={2}
    • Warning callout (<Alert variant='warning'>) about provider lock-in
    • Local useState<ProviderType | null> selection state
    • Inline error display sourced from useCardState
    • Step.Footer.Continue gated on isDisabled={isLastStep || !selected || card.isLoading}; shows a loading state during the async create call
    • Step.Footer.Previous left as-is (auto-disabled by isFirstStep)
    • Every user-visible string consumed via localizationKeys('configureSSO.selectProviderStep.*') (no inline literals)
  • ProviderCard (private to the file) — <SimpleButton variant='outline'> with a column-flex icon + label, height $32, gap $2, padding $1x5. Selected state renders a 4px boxShadow ring using theme.colors.$colorRing. aria-pressed mirrors the selected state for assistive tech.
  • Provider icons sourced from the img.clerk.com static CDN via iconImageUrl('okta') and iconImageUrl('saml'). Rendered as an inline <Span aria-hidden> with backgroundImage, mirroring ProviderIcon's non-mask-image branch — we don't wrap with <ProviderIcon> directly because its id prop union doesn't include 'saml_custom'.
  • elements/Step.tsx — minor Step.Header polish: top-align the inner row (align='start') and bump the title/description column gap to $2 to match the Figma. No behavior change.

State machine foundation

  • ConfigureSSOContext.tsx — extends the flow context with provider, setProvider, clearProvider, and createConnection. provider derives from enterpriseConnection?.provider ?? localProvider. createConnection is wrapped in useReverification, idempotent (no-ops when a connection already exists), and assembles the payload from the user's primary email domain + active organization id.
  • deriveInitialStep.ts (new) — pure helper that maps a connection state to the wizard step the user should land on: no connection → select-provider, no samlConnection.idpSsoUrlconfigure, otherwise → confirmation. Test step derivation is deferred (no synchronous "last test passed" signal).
  • ConfigureSSO.tsx — wires Wizard.initialStepId={deriveInitialStep(enterpriseConnection)} so reloads land on the right step.
  • SelectProviderStep Continue handler now setProvider(selected) → createConnection() → goNext(), all wrapped in useCardState (setLoading / setIdle / setError) and routed through handleError on rejection.
  • ProviderType renamed from UI-side ('okta' | 'custom_saml') to backend values ('saml_okta' | 'saml_custom') so the flow context, the resource call, and the resource's own provider field all agree.

Localization

  • @clerk/shared — adds the typed selectProviderStep namespace to __internal_LocalizationResource (under __experimental_configureSSO).
  • @clerk/localizations — adds English values in en-US.ts and translations for every other supported locale (~49 files).

Out of scope — planned follow-ups

  • Move createConnection into Verify Domain. Once chore(ui,shared,localizations): Add verify/add email address step to <ConfigureSSO /> #8520 merges, the create call moves to EnterVerificationCodeStep.onResolve so the connection is created after email + OTP verification, not on Select Provider Continue. The createConnection idempotency guard in this PR is what enables that move safely.
  • OIDC provider tile — explicitly deprioritized. SAML covers v1 enterprise demand.
  • Reset semantics returning the user back to Select Provider — wired from the Confirmation step in the same follow-up.

Test plan

  • Sandbox renders <__experimental_ConfigureSSO /> and lands on Select Provider on cold start (deriveInitialStep returns select-provider)
  • Breadcrumb shows 4 items (Verify domain / Configure / Test / Confirmation), all greyed because Select Provider is filtered out
  • Both SAML tiles render side-by-side with the real Okta + SAML logos loaded from img.clerk.com
  • Continue is disabled on entry; selecting a tile enables Continue and renders the 4px ring on the chosen tile
  • aria-pressed flips on the selected tile (verified via DevTools accessibility tree)
  • Clicking Continue shows loading state → enterprise connection created in backend → wizard advances to Verify Domain
  • Previous stays disabled throughout (this is the first step)
  • Backend failure on Continue → error rendered in the step body, wizard does not advance
  • Unit tests cover: mount, both tiles render, Continue gating, click-to-select, click-Continue → setProvider + createConnection + goNext invoked in order, loading state, error path
  • deriveInitialStep table-driven tests cover undefined connection / no samlConnection / no idpSsoUrl / has idpSsoUrl
  • Sandbox: reload mid-flow with connection but no metadata → mounts on Configure
  • Sandbox: reload mid-flow with connection + metadata → mounts on Confirmation
  • Sandbox visual pass with the localized strings resolved (pending manual QA)

Type of change

  • ✨ New feature (__experimental_* surface — no public API change)

@vercel
Copy link
Copy Markdown

vercel Bot commented May 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment May 12, 2026 2:26pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 7, 2026

🦋 Changeset detected

Latest commit: 62a608d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 20 packages
Name Type
@clerk/localizations Patch
@clerk/clerk-js Patch
@clerk/shared Patch
@clerk/ui Patch
@clerk/react Patch
@clerk/chrome-extension Patch
@clerk/expo Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/hono Patch
@clerk/msw Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/vue Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added the ui label May 7, 2026
@iagodahlem iagodahlem changed the base branch from main to iago/configure-sso-layers May 7, 2026 20:02
@iagodahlem iagodahlem force-pushed the iago/configure-sso-layers branch from 7dc3f44 to 94f83bd Compare May 11, 2026 13:34
Base automatically changed from iago/configure-sso-layers to main May 11, 2026 15:39
@iagodahlem iagodahlem changed the title Iago/orgs 1462 feat(ui): provider selection step for <__experimental_ConfigureSSO /> May 11, 2026
Comment on lines +57 to +61
align='start'
justify='between'
sx={theme => ({ gap: theme.space.$4 })}
>
<Col sx={theme => ({ gap: theme.space.$1x5, minWidth: 0 })}>
<Col sx={theme => ({ gap: theme.space.$2, minWidth: 0 })}>
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updates the badge display on the header.

@iagodahlem iagodahlem changed the title feat(ui): provider selection step for <__experimental_ConfigureSSO /> feat(ui,shared,localizations): provider selection step for <__experimental_ConfigureSSO /> May 11, 2026
@iagodahlem iagodahlem marked this pull request as ready for review May 12, 2026 13:29
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: b3fb7770-fa60-433a-9404-ef791e44f280

📥 Commits

Reviewing files that changed from the base of the PR and between 2529d2b and 62a608d.

📒 Files selected for processing (1)
  • packages/ui/src/components/ConfigureSSO/__tests__/deriveInitialStep.test.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/ui/src/components/ConfigureSSO/tests/deriveInitialStep.test.ts

📝 Walkthrough

Walkthrough

This PR implements the "Select Provider" step for the experimental ConfigureSSO wizard component. It adds support for selecting SAML providers (Okta Workforce and Custom SAML), with localized UI strings across 50 supported languages. The context layer is refactored to manage provider state, derive the wizard's entry step based on enterprise connection metadata, and provide an idempotent connection creation function. SelectProviderStep receives a complete implementation with provider selection cards, error handling, warnings about provider lock-in, and comprehensive test coverage. Supporting components are updated to integrate with the new state model.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • clerk/javascript#8493: Main PR builds on and extends the layered ConfigureSSO primitives introduced in #8493 (adds provider selection UI, wiring to the new Step/Wizard/Step.Footer primitives, a richer ConfigureSSO context, deriveInitialStep, and tests), so the changes are related.
  • clerk/javascript#8468: Both PRs modify the ConfigureSSO flow at the code level—adding/rewiring wizard steps, context/provider logic, and new ConfigureSSO step components (e.g., SelectProvider/deriveInitialStep and wizard plumbing)—so they are related.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: implementing a provider selection step UI and related flow plumbing for the experimental ConfigureSSO component.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the provider selection step UI, state machine foundation, and localization plumbing with clear context about objectives and scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/localizations/src/kk-KZ.ts`:
- Around line 185-198: The selectProviderStep localization object contains
English strings that must be translated to Kazakh; update the
selectProviderStep.title, subtitle, body.title, body.description,
saml.groupLabel, saml.okta, saml.customSaml, and warning in the kk-KZ.ts file to
Kazakh equivalents (or add an agreed temporary fallback translation) so the
locale no longer renders mixed-language UI; ensure you edit the
selectProviderStep object and preserve the same keys and structure.

In `@packages/ui/src/components/ConfigureSSO/__tests__/deriveInitialStep.test.ts`:
- Line 4: The test currently imports the type WizardStepId from
'../deriveInitialStep' but that type is actually exported from '../types';
update the import statement to import deriveInitialStep (function) from
'../deriveInitialStep' and WizardStepId (type) from '../types' so the file
imports "deriveInitialStep" and "WizardStepId" from their correct modules
(locate the current import line that references deriveInitialStep and change the
type import target to '../types').

In `@packages/ui/src/components/ConfigureSSO/ConfigureSSOContext.tsx`:
- Around line 59-76: The createConnectionFetcher function can call
createEnterpriseConnection multiple times before parent state updates because it
only checks the props enterpriseConnection; add an in-flight guard to make it
truly idempotent by introducing a local flag/ref (e.g., isCreatingRef) that is
checked at the start of createConnectionFetcher and set to true before calling
createEnterpriseConnection and cleared in finally, and also ensure you
short-circuit if createEnterpriseConnection returns an existing/duplicate
connection; keep the existing user.primaryEmailAddress and
session.lastActiveOrganizationId logic but use the guard around the
createEnterpriseConnection call (references: createConnectionFetcher,
enterpriseConnection, createEnterpriseConnection, user.primaryEmailAddress,
session.lastActiveOrganizationId).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: e524dd6f-7a5d-4904-9540-5bc12097a0c5

📥 Commits

Reviewing files that changed from the base of the PR and between 0f8aed2 and 6d20749.

📒 Files selected for processing (60)
  • .changeset/configure-sso-select-provider-step.md
  • packages/localizations/src/ar-SA.ts
  • packages/localizations/src/be-BY.ts
  • packages/localizations/src/bg-BG.ts
  • packages/localizations/src/bn-IN.ts
  • packages/localizations/src/ca-ES.ts
  • packages/localizations/src/cs-CZ.ts
  • packages/localizations/src/da-DK.ts
  • packages/localizations/src/de-DE.ts
  • packages/localizations/src/el-GR.ts
  • packages/localizations/src/en-GB.ts
  • packages/localizations/src/en-US.ts
  • packages/localizations/src/es-CR.ts
  • packages/localizations/src/es-ES.ts
  • packages/localizations/src/es-MX.ts
  • packages/localizations/src/es-UY.ts
  • packages/localizations/src/fa-IR.ts
  • packages/localizations/src/fi-FI.ts
  • packages/localizations/src/fr-FR.ts
  • packages/localizations/src/he-IL.ts
  • packages/localizations/src/hi-IN.ts
  • packages/localizations/src/hr-HR.ts
  • packages/localizations/src/hu-HU.ts
  • packages/localizations/src/id-ID.ts
  • packages/localizations/src/is-IS.ts
  • packages/localizations/src/it-IT.ts
  • packages/localizations/src/ja-JP.ts
  • packages/localizations/src/kk-KZ.ts
  • packages/localizations/src/ko-KR.ts
  • packages/localizations/src/mn-MN.ts
  • packages/localizations/src/ms-MY.ts
  • packages/localizations/src/nb-NO.ts
  • packages/localizations/src/nl-BE.ts
  • packages/localizations/src/nl-NL.ts
  • packages/localizations/src/pl-PL.ts
  • packages/localizations/src/pt-BR.ts
  • packages/localizations/src/pt-PT.ts
  • packages/localizations/src/ro-RO.ts
  • packages/localizations/src/ru-RU.ts
  • packages/localizations/src/sk-SK.ts
  • packages/localizations/src/sr-RS.ts
  • packages/localizations/src/sv-SE.ts
  • packages/localizations/src/ta-IN.ts
  • packages/localizations/src/te-IN.ts
  • packages/localizations/src/th-TH.ts
  • packages/localizations/src/tr-TR.ts
  • packages/localizations/src/uk-UA.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/types/localization.ts
  • packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx
  • packages/ui/src/components/ConfigureSSO/ConfigureSSOContext.tsx
  • packages/ui/src/components/ConfigureSSO/__tests__/deriveInitialStep.test.ts
  • packages/ui/src/components/ConfigureSSO/deriveInitialStep.ts
  • packages/ui/src/components/ConfigureSSO/elements/Step.tsx
  • packages/ui/src/components/ConfigureSSO/steps/ConfigureStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/__tests__/SelectProviderStep.test.tsx
  • packages/ui/src/components/ConfigureSSO/types.ts

Comment on lines +185 to +198
selectProviderStep: {
title: 'Select provider',
subtitle: 'Select the provider you are going to setup SSO for.',
body: {
title: 'Select your identity provider',
description: "We'll guide you through the detailed setup process next.",
},
saml: {
groupLabel: 'SAML',
okta: 'Okta Workforce',
customSaml: 'Custom SAML Provider',
},
warning: 'Once a provider is selected you cannot change again until the configuration is over',
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

kk-KZ Select Provider strings are still English.

Line 186 through Line 197 are not localized to Kazakh, so this locale will render mixed-language UI in the new SSO step.

Suggested temporary fallback until Kazakh copy is provided
     selectProviderStep: {
-      title: 'Select provider',
-      subtitle: 'Select the provider you are going to setup SSO for.',
+      title: undefined,
+      subtitle: undefined,
       body: {
-        title: 'Select your identity provider',
-        description: "We'll guide you through the detailed setup process next.",
+        title: undefined,
+        description: undefined,
       },
       saml: {
         groupLabel: 'SAML',
         okta: 'Okta Workforce',
-        customSaml: 'Custom SAML Provider',
+        customSaml: undefined,
       },
-      warning: 'Once a provider is selected you cannot change again until the configuration is over',
+      warning: undefined,
     },

As per coding guidelines, "Confirm that new translations are accurate, contextually appropriate, and match the intent of the original English strings."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/localizations/src/kk-KZ.ts` around lines 185 - 198, The
selectProviderStep localization object contains English strings that must be
translated to Kazakh; update the selectProviderStep.title, subtitle, body.title,
body.description, saml.groupLabel, saml.okta, saml.customSaml, and warning in
the kk-KZ.ts file to Kazakh equivalents (or add an agreed temporary fallback
translation) so the locale no longer renders mixed-language UI; ensure you edit
the selectProviderStep object and preserve the same keys and structure.

Comment thread packages/ui/src/components/ConfigureSSO/__tests__/deriveInitialStep.test.ts Outdated
Comment on lines +59 to +76
const createConnectionFetcher = React.useCallback(
async (selectedProvider: ProviderType) => {
if (enterpriseConnection) {
return;
}
if (!user?.primaryEmailAddress) {
throw new Error('Primary email required');
}

const emailDomain = user.primaryEmailAddress.emailAddress.split('@')[1];
const organizationId = session?.lastActiveOrganizationId ?? null;

await createEnterpriseConnection({
provider: selectedProvider,
name: emailDomain,
organizationId,
});
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

createConnection is not truly idempotent and can double-create connections.

enterpriseConnection is checked from props only, so repeated invocations before parent state refresh can call createEnterpriseConnection multiple times. That violates the intended idempotency and risks duplicate writes (with downstream stale/empty Configure step data).

Suggested fix
+  const hasCreatedConnectionRef = React.useRef(Boolean(enterpriseConnection));
+
+  React.useEffect(() => {
+    if (enterpriseConnection) {
+      hasCreatedConnectionRef.current = true;
+    }
+  }, [enterpriseConnection]);
+
   const createConnectionFetcher = React.useCallback(
     async (selectedProvider: ProviderType) => {
-      if (enterpriseConnection) {
+      if (hasCreatedConnectionRef.current || enterpriseConnection) {
         return;
       }
       if (!user?.primaryEmailAddress) {
         throw new Error('Primary email required');
       }
@@
       await createEnterpriseConnection({
         provider: selectedProvider,
         name: emailDomain,
         organizationId,
       });
+      hasCreatedConnectionRef.current = true;
     },
     [enterpriseConnection, user, session, createEnterpriseConnection],
   );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/components/ConfigureSSO/ConfigureSSOContext.tsx` around lines
59 - 76, The createConnectionFetcher function can call
createEnterpriseConnection multiple times before parent state updates because it
only checks the props enterpriseConnection; add an in-flight guard to make it
truly idempotent by introducing a local flag/ref (e.g., isCreatingRef) that is
checked at the start of createConnectionFetcher and set to true before calling
createEnterpriseConnection and cleared in finally, and also ensure you
short-circuit if createEnterpriseConnection returns an existing/duplicate
connection; keep the existing user.primaryEmailAddress and
session.lastActiveOrganizationId logic but use the guard around the
createEnterpriseConnection call (references: createConnectionFetcher,
enterpriseConnection, createEnterpriseConnection, user.primaryEmailAddress,
session.lastActiveOrganizationId).

Replace placeholder text in SelectProviderStep with a SAML provider selection UI featuring Okta Workforce and Custom SAML Provider cards. Introduces a ProviderCard component with selected state styling and adjusts Step header alignment to top-align with refined spacing.
…O step

- Add local useState for the selected provider (okta | custom_saml)
- Render real provider icons via iconImageUrl from img.clerk.com CDN
- Gate Step.Footer.Continue on selection
- Add provider lock-in warning Alert below the SAML group
- Drop placeholder icon Box and unused background color
Covers mount, tile labels and CDN icons, selection state via
aria-pressed, Continue gating, and goNext invocation on Continue.
…der card

Replace `<Box as='span'>` with the dedicated `<Span>` primitive for the provider icon wrapper in `SelectProviderStep`, simplifying the markup and imports.
iagodahlem added 10 commits May 12, 2026 10:44
…gureSSO

Wire every user-visible string in the Select Provider step through
@clerk/localizations. Adds a selectProviderStep namespace under
__experimental_configureSSO with title, subtitle, body title/description,
SAML group label + provider labels, and the lock-in warning. Populates
en-US and translates to all ~49 supported locales.
Adds provider/setProvider/clearProvider/createConnection to the flow context
so the Select Provider step can persist the chosen provider and create the
enterprise connection on Continue. createConnection is wrapped in
useReverification and is idempotent — it no-ops when an enterprise
connection already exists.
Pure helper that returns the wizard step a user should mount on based on
the state of their enterprise connection. No connection lands on Select
Provider, an existing connection without SAML IdP metadata lands on
Configure, and a fully configured connection lands on Confirmation.
Covered by a table-driven unit test.
Wires Wizard.initialStepId via deriveInitialStep so the ConfigureSSO
wizard re-mounts on the right step after reload. Renames the local
ProviderType ids in Select Provider from 'okta' / 'custom_saml' to the
backend values 'saml_okta' / 'saml_custom' so the Continue handler can
forward them directly. Continue now sets the provider on the flow
context, calls createConnection, and advances the wizard — wrapped in
useCardState for loading and error display following the same pattern
as Verify Domain.
Mocks the ConfigureSSO flow context so the Continue handler can be
verified end-to-end. Asserts setProvider is called with the backend
provider id, followed by createConnection, then goNext, and adds
coverage for the loading state and the rejection path where the wizard
must not advance and the error must surface in the card.
Notes the flow-context extensions, deriveInitialStep helper, and the
createConnection-on-Continue behavior so the published changelog
matches what the PR actually ships.
Move ProviderType and WizardStepId into a shared types module and lift initialStepId derivation into the flow context so consumers read a single value instead of recomputing it. Replace the flat PROVIDER_OPTIONS list with grouped PROVIDER_GROUPS to support multiple provider categories, switch connection creation to __internal_useUserEnterpriseConnections, and drop the unused clearProvider/goPrev affordances on the Select Provider step.
…ification

- createConnection now accepts the provider as a parameter instead of reading
  it from React state (which was stale within the same tick as setProvider)
- Restore the useReverification wrap on createConnection, matching the rest of
  @clerk/ui's user.* mutation pattern (createEmailAddress, delete, createTOTP,
  setPrimary, createWeb3Wallet, …) — handles backend session-reverification
  policy transparently when present, no-ops otherwise
…ureSSO

- Hoist the __internal_useUserEnterpriseConnections call to ConfigureSSOCardContent
  so the provider receives the data and the create mutation as props instead of
  calling the hook a second time
- Drop the unused isLoading from the provider surface; the load gate upstream
  already consumes it
- Rename ConfigureSSOFlowProvider → ConfigureSSOProvider, useConfigureSSOFlow →
  useConfigureSSO, drop the leftover "Flow" suffix
Pull the enterprise connection from ConfigureSSOContext inside ConfigureStep and render its SAML ACS URL as the single sign-on URL, replacing the placeholder text. Drop the now-unused isLastStep guard from the Select Provider continue button.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/localizations/src/ta-IN.ts`:
- Around line 189-202: The new configureSSO.selectProviderStep strings in ta-IN
are still in English; update the selectProviderStep object (keys: title,
subtitle, body.title, body.description, saml.groupLabel, saml.okta,
saml.customSaml, and warning) with accurate Tamil translations that match the
original meanings and UI context (e.g., "Select provider", "Select the provider
you are going to setup SSO for.", "Select your identity provider", "We'll guide
you through the detailed setup process next.", SAML group label, "Okta
Workforce", "Custom SAML Provider", and the warning about not being able to
change provider). Keep phrasing concise and natural for Tamil UI, and verify
translations for tone and clarity before committing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: e475d23a-a182-4164-af5b-10b95b32aa45

📥 Commits

Reviewing files that changed from the base of the PR and between 6d20749 and 2529d2b.

📒 Files selected for processing (60)
  • .changeset/configure-sso-select-provider-step.md
  • packages/localizations/src/ar-SA.ts
  • packages/localizations/src/be-BY.ts
  • packages/localizations/src/bg-BG.ts
  • packages/localizations/src/bn-IN.ts
  • packages/localizations/src/ca-ES.ts
  • packages/localizations/src/cs-CZ.ts
  • packages/localizations/src/da-DK.ts
  • packages/localizations/src/de-DE.ts
  • packages/localizations/src/el-GR.ts
  • packages/localizations/src/en-GB.ts
  • packages/localizations/src/en-US.ts
  • packages/localizations/src/es-CR.ts
  • packages/localizations/src/es-ES.ts
  • packages/localizations/src/es-MX.ts
  • packages/localizations/src/es-UY.ts
  • packages/localizations/src/fa-IR.ts
  • packages/localizations/src/fi-FI.ts
  • packages/localizations/src/fr-FR.ts
  • packages/localizations/src/he-IL.ts
  • packages/localizations/src/hi-IN.ts
  • packages/localizations/src/hr-HR.ts
  • packages/localizations/src/hu-HU.ts
  • packages/localizations/src/id-ID.ts
  • packages/localizations/src/is-IS.ts
  • packages/localizations/src/it-IT.ts
  • packages/localizations/src/ja-JP.ts
  • packages/localizations/src/kk-KZ.ts
  • packages/localizations/src/ko-KR.ts
  • packages/localizations/src/mn-MN.ts
  • packages/localizations/src/ms-MY.ts
  • packages/localizations/src/nb-NO.ts
  • packages/localizations/src/nl-BE.ts
  • packages/localizations/src/nl-NL.ts
  • packages/localizations/src/pl-PL.ts
  • packages/localizations/src/pt-BR.ts
  • packages/localizations/src/pt-PT.ts
  • packages/localizations/src/ro-RO.ts
  • packages/localizations/src/ru-RU.ts
  • packages/localizations/src/sk-SK.ts
  • packages/localizations/src/sr-RS.ts
  • packages/localizations/src/sv-SE.ts
  • packages/localizations/src/ta-IN.ts
  • packages/localizations/src/te-IN.ts
  • packages/localizations/src/th-TH.ts
  • packages/localizations/src/tr-TR.ts
  • packages/localizations/src/uk-UA.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/types/localization.ts
  • packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx
  • packages/ui/src/components/ConfigureSSO/ConfigureSSOContext.tsx
  • packages/ui/src/components/ConfigureSSO/__tests__/deriveInitialStep.test.ts
  • packages/ui/src/components/ConfigureSSO/deriveInitialStep.ts
  • packages/ui/src/components/ConfigureSSO/elements/Step.tsx
  • packages/ui/src/components/ConfigureSSO/steps/ConfigureStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/__tests__/SelectProviderStep.test.tsx
  • packages/ui/src/components/ConfigureSSO/types.ts
✅ Files skipped from review due to trivial changes (31)
  • packages/localizations/src/bn-IN.ts
  • .changeset/configure-sso-select-provider-step.md
  • packages/ui/src/components/ConfigureSSO/types.ts
  • packages/localizations/src/hr-HR.ts
  • packages/localizations/src/es-UY.ts
  • packages/localizations/src/ro-RO.ts
  • packages/localizations/src/cs-CZ.ts
  • packages/localizations/src/is-IS.ts
  • packages/localizations/src/be-BY.ts
  • packages/localizations/src/en-GB.ts
  • packages/localizations/src/bg-BG.ts
  • packages/localizations/src/fa-IR.ts
  • packages/localizations/src/es-MX.ts
  • packages/localizations/src/sr-RS.ts
  • packages/localizations/src/mn-MN.ts
  • packages/localizations/src/pt-BR.ts
  • packages/localizations/src/el-GR.ts
  • packages/localizations/src/kk-KZ.ts
  • packages/localizations/src/nl-NL.ts
  • packages/localizations/src/ms-MY.ts
  • packages/localizations/src/sk-SK.ts
  • packages/localizations/src/id-ID.ts
  • packages/localizations/src/he-IL.ts
  • packages/localizations/src/sv-SE.ts
  • packages/localizations/src/hu-HU.ts
  • packages/localizations/src/te-IN.ts
  • packages/localizations/src/pt-PT.ts
  • packages/localizations/src/ja-JP.ts
  • packages/localizations/src/nb-NO.ts
  • packages/localizations/src/da-DK.ts
  • packages/localizations/src/hi-IN.ts
🚧 Files skipped from review as they are similar to previous changes (23)
  • packages/localizations/src/uk-UA.ts
  • packages/localizations/src/ar-SA.ts
  • packages/ui/src/components/ConfigureSSO/elements/Step.tsx
  • packages/ui/src/components/ConfigureSSO/tests/deriveInitialStep.test.ts
  • packages/localizations/src/ru-RU.ts
  • packages/ui/src/components/ConfigureSSO/deriveInitialStep.ts
  • packages/localizations/src/es-ES.ts
  • packages/localizations/src/fr-FR.ts
  • packages/ui/src/components/ConfigureSSO/steps/ConfigureStep.tsx
  • packages/localizations/src/en-US.ts
  • packages/localizations/src/th-TH.ts
  • packages/localizations/src/es-CR.ts
  • packages/localizations/src/vi-VN.ts
  • packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/nl-BE.ts
  • packages/shared/src/types/localization.ts
  • packages/localizations/src/tr-TR.ts
  • packages/localizations/src/ko-KR.ts
  • packages/localizations/src/fi-FI.ts
  • packages/ui/src/components/ConfigureSSO/steps/tests/SelectProviderStep.test.tsx
  • packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx
  • packages/ui/src/components/ConfigureSSO/ConfigureSSOContext.tsx

Comment on lines +189 to +202
selectProviderStep: {
title: 'Select provider',
subtitle: 'Select the provider you are going to setup SSO for.',
body: {
title: 'Select your identity provider',
description: "We'll guide you through the detailed setup process next.",
},
saml: {
groupLabel: 'SAML',
okta: 'Okta Workforce',
customSaml: 'Custom SAML Provider',
},
warning: 'Once a provider is selected you cannot change again until the configuration is over',
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

ta-IN new SSO provider strings are not translated (still English).

Line 190 through Line 201 add configureSSO.selectProviderStep values in English, which causes mixed-language UI in the Tamil locale and leaves the new keys effectively untranslated for ta-IN. Please provide Tamil translations for this block before merge.

As per coding guidelines: “Confirm that new translations are accurate, contextually appropriate, and match the intent of the original English strings” and “If you notice missing translations for new keys, flag them for completion.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/localizations/src/ta-IN.ts` around lines 189 - 202, The new
configureSSO.selectProviderStep strings in ta-IN are still in English; update
the selectProviderStep object (keys: title, subtitle, body.title,
body.description, saml.groupLabel, saml.okta, saml.customSaml, and warning) with
accurate Tamil translations that match the original meanings and UI context
(e.g., "Select provider", "Select the provider you are going to setup SSO for.",
"Select your identity provider", "We'll guide you through the detailed setup
process next.", SAML group label, "Okta Workforce", "Custom SAML Provider", and
the warning about not being able to change provider). Keep phrasing concise and
natural for Tamil UI, and verify translations for tone and clarity before
committing.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 12, 2026

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8503

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8503

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8503

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8503

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@8503

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8503

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8503

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8503

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8503

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8503

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8503

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8503

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8503

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8503

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8503

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8503

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8503

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8503

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8503

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8503

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8503

commit: 62a608d

@iagodahlem iagodahlem requested a review from LauraBeatris May 12, 2026 13:58
Comment on lines +21 to +23
if (!connection.samlConnection?.idpSsoUrl) {
return 'configure';
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would translate as "minimum IdP configuration" -> we could extract to a boolean as well or add a comment, but just to highlight that this can also be extended in the future for OIDC, we'll prob reuse the same function here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants