Skip to content

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Jan 22, 2026

Summary

Splits the setActive method into two purpose-specific methods for Core 3:

  • selectSession(session, options?) - For session selection (sign-in, sign-up, multi-session switching, sign out)
  • selectOrganization(organization, options?) - For organization selection (org switching, personal workspace)

This is a breaking change that removes setActive from hook return types entirely (clean break approach).

Changes

New Methods on Clerk Object

  • clerk.selectSession(session, options?) - wraps session-related setActive calls
  • clerk.selectOrganization(organization, options?) - wraps organization-related setActive calls

Hook Return Type Changes

Hook Before After
useSignIn() setActive selectSession
useSignUp() setActive selectSession
useSessionList() setActive selectSession
useOrganizationList() setActive selectOrganization

Internal Window Hooks (Next.js)

  • __internal_onBeforeSetActive__internal_onBeforeSelectSession
  • __internal_onAfterSetActive__internal_onAfterSelectSession

Migration Example

Before:

const { setActive } = useSignIn();
await setActive({ session: createdSessionId });

const { setActive } = useOrganizationList();
await setActive({ organization: org });

After:

const { selectSession } = useSignIn();
await selectSession(createdSessionId);

const { selectOrganization } = useOrganizationList();
await selectOrganization(org);

Packages Affected

  • @clerk/clerk-js
  • @clerk/shared
  • @clerk/react
  • @clerk/nextjs
  • @clerk/vue
  • @clerk/expo
  • @clerk/ui

Test Plan

  • Build passes
  • Unit tests updated
  • Codemod for user migration

Linear

Closes USER-4041

Summary by CodeRabbit

  • Breaking Changes

    • Removed setActive method; replaced with selectSession() and selectOrganization() methods.
  • New Features

    • selectSession() and selectOrganization() methods now support optional navigation options including redirectUrl and navigate callbacks.
    • Updated hook return values: useSignIn, useSignUp, and useSessionList now return selectSession; useOrganizationList returns selectOrganization.

✏️ Tip: You can customize this high-level summary in your review settings.

Add two new purpose-specific methods to replace the generic setActive:
- selectSession: For session selection (sign-in, sign-up, session switching)
- selectOrganization: For organization selection (org switching, personal workspace)

Changes:
- Add SelectSessionOptions, SelectOrganizationOptions types
- Add selectSession and selectOrganization methods to Clerk core
- Update React hooks (useSignIn, useSignUp) to return selectSession
- Update shared hooks (useSessionList, useOrganizationList) with new methods
- Update framework integrations (Next.js, Vue, Expo)
- Rename internal hooks: __internal_onBeforeSelectSession, __internal_onAfterSelectSession

setActive is currently kept as deprecated for backwards compatibility.
- Remove setActive from UseSignInReturn, UseSignUpReturn, UseSessionListReturn, UseOrganizationListReturn types
- Update React hooks (useSignIn, useSignUp) to return only selectSession
- Update shared hooks (useSessionList, useOrganizationList) to return only selectSession/selectOrganization
- Update Vue composables (useSignIn, useSignUp, useSessionList) to return only selectSession
- Update Expo hooks (useSSO, useOAuth, useSignInWithApple) to return only selectSession
- Update UI components to use selectOrganization from useOrganizationList
- Rename useSetSessionWithTimeout to useSelectSessionWithTimeout
@changeset-bot
Copy link

changeset-bot bot commented Jan 22, 2026

🦋 Changeset detected

Latest commit: a6880dd

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

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

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

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

@vercel
Copy link

vercel bot commented Jan 22, 2026

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

Project Deployment Review Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jan 22, 2026 5:01pm

Request Review

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 22, 2026

Open in StackBlitz

@clerk/agent-toolkit

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

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: a6880dd

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

This pull request replaces the setActive method with two purpose-specific methods on the Clerk API: selectSession and selectOrganization. The change removes setActive from the public Clerk object and all related hooks including useSignIn, useSignUp, useSessionList, and useOrganizationList. Internal lifecycle hooks are renamed from __internal_onBeforeSetActive and __internal_onAfterSetActive to __internal_onBeforeSelectSession and __internal_onAfterSelectSession. New options interfaces SelectSessionOptions and SelectOrganizationOptions are introduced to support configurable navigation behavior. Updates are applied across multiple packages including clerk-js, React, Vue, Expo, Next.js, and UI components.

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The PR implements session/organization selection renaming, but uses 'selectSession'/'selectOrganization' instead of the 'setSelected' proposed in USER-4041. Clarify whether 'selectSession' and 'selectOrganization' meet the intent of USER-4041's renaming objective, or if 'setSelected' naming was preferred but changed during implementation.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately reflects the main change: splitting setActive into two purpose-specific methods (selectSession and selectOrganization).
Out of Scope Changes check ✅ Passed All changes are directly related to splitting setActive into selectSession and selectOrganization across the codebase, with no unrelated modifications detected.

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


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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/clerk-js/src/core/clerk.ts`:
- Around line 1658-1673: The setActiveNavigate wrapper currently uses
this.organization when the external `organization` config is a string, which can
be stale; instead resolve the selected org from the activating session before
calling `navigate`. In the async function `setActiveNavigate` (wrapping
`navigate` and using `SessionResource`), if `organization === null` pass null;
if `typeof organization === 'string'` derive the org from the provided `session`
(prefer `session.lastActiveOrganizationId` or fall back to finding a membership
with matching organization id in `session.memberships`) and pass that resolved
id/object to `navigate`; otherwise pass the `organization` object directly.
Update the resolution logic in `setActiveNavigate` to use
`session.lastActiveOrganizationId`/`session.memberships` instead of
`this.organization` before invoking `navigate` and handling string return values
with `this.navigate`.

In `@packages/expo/src/hooks/useSignInWithGoogle.types.ts`:
- Around line 7-10: The implementation in useSignInWithGoogle.ts returns/exports
a field named setActive while the public type
StartGoogleAuthenticationFlowReturnType expects selectSession; update the
implementation to return selectSession (rename setActive to selectSession where
it is constructed/returned) or re-export StartGoogleAuthenticationFlowReturnType
from useSignInWithGoogle.ts so there’s a single source of truth; ensure the
function that builds the return object (the startGoogleAuthenticationFlow / hook
return value) and any local type aliases are updated to use selectSession and
the SelectSessionHook symbol.

Comment on lines +1658 to +1673
// Convert navigate callback to setActive format if provided
const setActiveNavigate = navigate
? async ({ session }: { session: SessionResource }) => {
// Resolve the organization for the callback
const org =
organization === null
? null
: typeof organization === 'string'
? (this.organization ?? null)
: organization;

const result = await navigate({ session, organization: org });
if (typeof result === 'string') {
await this.navigate(result);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use the selected organization when invoking navigate.

When organization is a string, the callback receives this.organization (the current org), not the newly selected one. This can route to the wrong org or personal workspace. Resolve the organization from the session being activated (e.g., via session.lastActiveOrganizationId or memberships) before calling navigate.

🛠️ Proposed fix
-          const org =
-            organization === null
-              ? null
-              : typeof organization === 'string'
-                ? (this.organization ?? null)
-                : organization;
+          const org =
+            organization === null
+              ? null
+              : typeof organization === 'string'
+                ? session.user.organizationMemberships.find(
+                    mem => mem.organization.id === session.lastActiveOrganizationId,
+                  )?.organization ?? null
+                : organization;
🤖 Prompt for AI Agents
In `@packages/clerk-js/src/core/clerk.ts` around lines 1658 - 1673, The
setActiveNavigate wrapper currently uses this.organization when the external
`organization` config is a string, which can be stale; instead resolve the
selected org from the activating session before calling `navigate`. In the async
function `setActiveNavigate` (wrapping `navigate` and using `SessionResource`),
if `organization === null` pass null; if `typeof organization === 'string'`
derive the org from the provided `session` (prefer
`session.lastActiveOrganizationId` or fall back to finding a membership with
matching organization id in `session.memberships`) and pass that resolved
id/object to `navigate`; otherwise pass the `organization` object directly.
Update the resolution logic in `setActiveNavigate` to use
`session.lastActiveOrganizationId`/`session.memberships` instead of
`this.organization` before invoking `navigate` and handling string return values
with `this.navigate`.

Comment on lines 7 to 10
export type StartGoogleAuthenticationFlowReturnType = {
createdSessionId: string | null;
setActive?: SetActive;
selectSession?: SelectSessionHook;
signIn?: SignInResource;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Align runtime return shape with renamed field

StartGoogleAuthenticationFlowReturnType now exposes selectSession (Line 9), but packages/expo/src/hooks/useSignInWithGoogle.ts still defines the return type with setActive (lines 10–15 in that file). If the implementation still returns setActive, consumers will see selectSession as undefined or hit type/runtime mismatches. Please update the implementation (and its local type definition if still present) to return selectSession, or re-export this type to keep a single source of truth.

🤖 Prompt for AI Agents
In `@packages/expo/src/hooks/useSignInWithGoogle.types.ts` around lines 7 - 10,
The implementation in useSignInWithGoogle.ts returns/exports a field named
setActive while the public type StartGoogleAuthenticationFlowReturnType expects
selectSession; update the implementation to return selectSession (rename
setActive to selectSession where it is constructed/returned) or re-export
StartGoogleAuthenticationFlowReturnType from useSignInWithGoogle.ts so there’s a
single source of truth; ensure the function that builds the return object (the
startGoogleAuthenticationFlow / hook return value) and any local type aliases
are updated to use selectSession and the SelectSessionHook symbol.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants