diff --git a/.changeset/api-keys-org-context-user-disabled.md b/.changeset/api-keys-org-context-user-disabled.md new file mode 100644 index 00000000000..9b407374b0a --- /dev/null +++ b/.changeset/api-keys-org-context-user-disabled.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Fix the standalone `` component failing to render when an organization is active and user API keys are disabled but organization API keys are enabled. The component now correctly checks the user API keys setting only when no organization is active. diff --git a/integration/tests/api-keys-component.test.ts b/integration/tests/api-keys-component.test.ts index 3e37d345b7f..ae4449540cd 100644 --- a/integration/tests/api-keys-component.test.ts +++ b/integration/tests/api-keys-component.test.ts @@ -388,6 +388,44 @@ test.describe('api keys component @machine', () => { await u.page.unrouteAll(); }); + test('standalone API keys component renders in org context when user API keys are disabled', async ({ + page, + context, + }) => { + const u = createTestUtils({ app, page, context }); + + await u.po.signIn.goTo(); + await u.po.signIn.waitForMounted(); + await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password }); + await u.po.expect.toBeSignedIn(); + + await u.po.organizationSwitcher.goTo(); + await u.po.organizationSwitcher.waitForMounted(); + await u.po.organizationSwitcher.waitForAnOrganizationToSelected(); + + await mockAPIKeysEnvironmentSettings(u.page, { user_api_keys_enabled: false }); + + let capturedSubject: string | null = null; + const apiKeyRequestPromise = u.page.waitForRequest(request => { + if (request.url().includes('api_keys')) { + const url = new URL(request.url()); + capturedSubject = url.searchParams.get('subject'); + return true; + } + return false; + }); + + await u.po.page.goToRelative('/api-keys'); + await u.po.apiKeys.waitForMounted(); + await expect(u.page.locator('.cl-apiKeys-root')).toBeVisible(); + + // Org API keys are listed, so the subject must be the organization + await apiKeyRequestPromise; + expect(capturedSubject).toBe(fakeOrganization.organization.id); + + await u.page.unrouteAll(); + }); + test.describe('api key list invalidation', () => { // Helper function to count actual API key rows (not empty state) const createAPIKeyCountHelper = (u: any) => async () => { diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index d9d61e219dd..b19474cdc65 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -1454,7 +1454,7 @@ export class Clerk implements ClerkInterface { return; } - if (disabledUserAPIKeysFeature(this, this.environment)) { + if (!this.organization && disabledUserAPIKeysFeature(this, this.environment)) { if (this.#instanceType === 'development') { throw new ClerkRuntimeError(warnings.cannotRenderAPIKeysComponentForUserWhenDisabled, { code: CANNOT_RENDER_API_KEYS_USER_DISABLED_ERROR_CODE,