Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts by NicolasLopes7 · Pull Request #8091 · clerk/javascript · GitHub
Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts by NicolasLopes7 · Pull Request #8091 · clerk/javascript · GitHub
Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts by NicolasLopes7 · Pull Request #8091 · clerk/javascript · GitHub
Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts by NicolasLopes7 · Pull Request #8091 · clerk/javascript · GitHub
Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts by NicolasLopes7 · Pull Request #8091 · clerk/javascript · GitHub
Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts by NicolasLopes7 · Pull Request #8091 · clerk/javascript · GitHub
Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts by NicolasLopes7 · Pull Request #8091 · clerk/javascript · GitHub
Skip to content

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts - #8091

Merged
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking
Mar 26, 2026
Merged

feat(ui,clerk-js,shared): Allow to link external accounts to enterprise accounts#8091
LauraBeatris merged 9 commits into
mainfrom
nicolas/enterprise-connections-account-linking

Conversation

@NicolasLopes7

@NicolasLopes7NicolasLopes7 commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new feature for the enterprise accounts section in UserProfile - it allows to connect to enterprise accounts based on existing enterprise connections for the current user's active organization.

This is only possible if the enterprise connection has an allowOrganizationAccountLinking flag.

CleanShot.2026-03-23.at.23.27.45.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • New Features

    • Users can now link external accounts to enterprise accounts through UserProfile
    • Enterprise Accounts section includes a new "Connect account" button for managing account linkage
  • Localization

    • Added translations for the Enterprise Accounts interface across 40+ languages

@vercel

vercelBot commented Mar 16, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentMar 26, 2026 6:16pm

Request Review

@changeset-bot

changeset-botBot commented Mar 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6d6d5dc

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

This PR includes changesets to release 21 packages
NameType
@clerk/localizationsMinor
@clerk/clerk-jsMinor
@clerk/sharedMinor
@clerk/uiMinor
@clerk/reactPatch
@clerk/chrome-extensionPatch
@clerk/expoPatch
@clerk/agent-toolkitPatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/expo-passkeysPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/honoPatch
@clerk/mswPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/tanstack-react-startPatch
@clerk/testingPatch
@clerk/vuePatch

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

@NicolasLopes7NicolasLopes7 changed the title wipsupport enteprise account linkingMar 16, 2026
Comment threadpackages/localizations/src/en-US.ts Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
Comment threadpackages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx Outdated
@NicolasLopes7

Copy link
Copy Markdown
ContributorAuthor

Todo: filter enterprise connections that the user already have an account with.

Also only display the "connect enterprise account" button if there's at least one available connection to connect

@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from b3579e5 to 5ae8252CompareMarch 23, 2026 19:31
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 5ae8252 to a76363dCompareMarch 23, 2026 22:59
@LauraBeatrisLauraBeatris changed the title support enteprise account linkingfeat(ui): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from c97b99e to 609631bCompareMarch 23, 2026 23:26
@LauraBeatrisLauraBeatris changed the title feat(ui): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris changed the title feat(ui,clerk-js): Allow to link external accounts to enterprise accountsfeat(ui,clerk-js,shared): Allow to link external accounts to enterprise accountsMar 23, 2026
@LauraBeatrisLauraBeatris self-assigned this Mar 24, 2026
@LauraBeatris
LauraBeatrisforce-pushed the nicolas/enterprise-connections-account-linking branch from 120dab9 to e2f89fdCompareMarch 24, 2026 02:31
@LauraBeatris
LauraBeatris marked this pull request as ready for review March 24, 2026 02:32
@pkg-pr-new

pkg-pr-newBot commented Mar 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8091

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 6d6d5dc

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx`:
- Around line 130-135: The current filter for linkableEnterpriseConnections
deduplicates against activeEnterpriseAccounts (a display subset), causing
already-linked connections that are omitted from that subset to be offered again
and break createExternalAccount; change the dedupe target to the full
linked-account set instead of activeEnterpriseAccounts — i.e., when computing
linkableEnterpriseConnections, compare c.id against the complete list of the
user's enterprise/external accounts (the canonical linked-account collection
returned by your user data hook or state) rather than activeEnterpriseAccounts
so duplicates are correctly excluded before calling createExternalAccount.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 387b1b9b-a838-4467-a544-d2db9c9c039b

📥 Commits

Reviewing files that changed from the base of the PR and between 519aff7 and 239b897.

📒 Files selected for processing (50)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

const loadingKey = `enterprise_${connection.id}`;

const createExternalAccount = useReverification(() => {
const redirectUrl = isModal ? appendModalState({ url: window.location.href, componentName }) : window.location.href;

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.

I wonder if we shouldn't abstract this logic somehow into a hook, I would personally forget all the time to check for the modal mode to append the modal state 😅

Comment on lines +33 to +36
return user?.createExternalAccount({
enterpriseConnectionId: connection.id,
redirectUrl,
});

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.

❓ A few questions here around the data fetching:

  • When we use the user.createExternalAccount is that using the User resource directly?
  • Does that handles invalidating the /me/enterprise_connections query?
  • I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?
  • In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

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.

I think in this case it doesn't matter because we always redirect to the IdP to sign in and connect the account right?

Correct, so the IdP would redirect back to the app, with the UserProfile opened, where it'll trigger /me/enterprise_connections again

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.

In this case, would be worth making this call a hook in the react package? I wonder where do we draw the line between create a custom hook or the resource directly.

Since this logic is specific for the enterprise account section, so makes sense to have it in there, and only rely on the mutation + query

We could extract this to a hook within the same module at least for semantics

return createExternalAccount()
.then(res => {
if (res?.verification?.externalVerificationRedirectURL) {
void sleep(2000).then(() => card.setIdle(loadingKey));

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.

Is the sleep just cosmetic to make the windowNavigate smoother?

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.

Mostly presentational, I've kept it consistent with the same logic we have to connect to external accounts

If navigation is slow, loading eventually clears after 2s instead of staying stuck forever

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: The early return in ConnectedAccountsSection that returns
null when accounts.length === 0 hides the AddConnectedAccount UI; change the
logic so the component only returns null when there are no accounts AND creation
is not allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: d0d40689-640c-4223-bd5f-984cd849dcbe

📥 Commits

Reviewing files that changed from the base of the PR and between 239b897 and cd6ca61.

📒 Files selected for processing (51)
  • 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/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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

Comment on lines +70 to +72
if (accounts.length === 0) {
return null;
}

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

Blocking: early return hides “Add connected account” for first-time users

Returning null when accounts.length === 0 prevents rendering AddConnectedAccount when shouldAllowCreation is true, so users with no existing accounts cannot connect one from this section.

Suggested fix
- if (accounts.length === 0) {- return null;- }+ if (accounts.length === 0 && !shouldAllowCreation) {+ return null;+ }

As per coding guidelines: "Only comment on issues that would block merging... focus strictly on merge-blocking concerns."

📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(accounts.length===0){
returnnull;
}
if(accounts.length===0&&!shouldAllowCreation){
returnnull;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, The early return in ConnectedAccountsSection that returns null
when accounts.length === 0 hides the AddConnectedAccount UI; change the logic so
the component only returns null when there are no accounts AND creation is not
allowed. Specifically, update the conditional around accounts to check
shouldAllowCreation (or the prop/name used) and render the AddConnectedAccount
component when shouldAllowCreation is true even if accounts.length === 0; keep
the existing rendering path for when accounts exist (map over accounts) and only
skip rendering the whole section if no accounts AND shouldAllowCreation is
false.

@coderabbitaicoderabbitaiBot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/clerk-js/src/core/resources/EnterpriseAccount.ts (1)

108-123: ⚠️ Potential issue | 🔴 Critical

Populate protocol when hydrating enterprise connections.

User.getEnterpriseConnections() now returns EnterpriseAccountConnection directly, but this mapper never copies data.protocol. Every fetched connection will expose protocol as undefined, and __internal_toSnapshot() will persist that broken value back out.

Suggested fix
 this.name = data.name;
this.domain = data.domain;
this.active = data.active;
+ this.protocol = data.protocol;
this.provider = data.provider;
this.logoPublicUrl = data.logo_public_url;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts` around lines 108 -
123, The fromJSON mapper in EnterpriseAccountConnection (method protected
fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
♻️ Duplicate comments (1)
packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx (1)

70-72: ⚠️ Potential issue | 🔴 Critical

Blocking: early return hides account creation flow.

At Line 70, returning null when accounts.length === 0 also hides AddConnectedAccount even when shouldAllowCreation is true, so users with no current accounts cannot connect one.

Suggested fix
- if (accounts.length === 0) {+ if (accounts.length === 0 && !shouldAllowCreation) {
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx` around
lines 70 - 72, ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx`:
- Around line 34-50: The cache key for the query currently only uses userId, so
toggling withOrganizationAccountLinking still hits the same cache; update the
cache key generation by passing withOrganizationAccountLinking into
useUserEnterpriseConnectionsCacheKeys (so the returned queryKey/stableKey
include that flag) and then keep using those keys in useClerkQuery and
useClearQueriesOnSignOut; modify the call site where
useUserEnterpriseConnectionsCacheKeys is invoked and the cache key factory (the
implementation behind useUserEnterpriseConnectionsCacheKeys) to include
withOrganizationAccountLinking as part of the key.
---
Outside diff comments:
In `@packages/clerk-js/src/core/resources/EnterpriseAccount.ts`:
- Around line 108-123: The fromJSON mapper in EnterpriseAccountConnection
(method protected fromJSON(...)) never copies the protocol field, so hydrated
EnterpriseAccountConnection instances end up with protocol undefined and
__internal_toSnapshot() will persist that bad value; fix by assigning
this.protocol = data.protocol inside fromJSON alongside the other property
mappings so protocol is populated when hydrating and subsequently serialized.
---
Duplicate comments:
In `@packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx`:
- Around line 70-72: ConnectedAccountsSection currently returns early when
accounts.length === 0 which hides the AddConnectedAccount flow; remove the
unconditional early return and instead render the section container even when
accounts is empty, conditionally showing either the list of accounts (when
accounts.length > 0) or an empty state that includes AddConnectedAccount when
shouldAllowCreation is true; update the rendering logic in
ConnectedAccountsSection (references: accounts, shouldAllowCreation,
AddConnectedAccount) so AddConnectedAccount is rendered whenever
shouldAllowCreation is true regardless of accounts.length.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 8580e5a6-d514-4c36-995d-f1c44126fa9a

📥 Commits

Reviewing files that changed from the base of the PR and between cd6ca61 and e10e17f.

📒 Files selected for processing (64)
  • .changeset/large-cameras-talk.md
  • packages/clerk-js/src/core/resources/EnterpriseAccount.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • 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/utils/enUS_v4.ts
  • packages/localizations/src/vi-VN.ts
  • packages/localizations/src/zh-CN.ts
  • packages/localizations/src/zh-TW.ts
  • packages/shared/src/react/hooks/index.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.shared.ts
  • packages/shared/src/react/hooks/useUserEnterpriseConnections.tsx
  • packages/shared/src/react/stable-keys.ts
  • packages/shared/src/types/enterpriseAccount.ts
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/user.ts
  • packages/ui/src/components/UserProfile/ConnectedAccountsSection.tsx
  • packages/ui/src/components/UserProfile/EnterpriseAccountsSection.tsx

@LauraBeatris
LauraBeatris merged commit 1827b50 into mainMar 26, 2026
42 checks passed
@LauraBeatris
LauraBeatris deleted the nicolas/enterprise-connections-account-linking branch March 26, 2026 18:52
Sign up for freeto 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.

3 participants

@NicolasLopes7@iagodahlem@LauraBeatris