Skip to content

feat(clerk-js): Introduce navigate for setActive #6486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Aug 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
ddff9e4
Remove `__internal_navigateToTaskIfAvailable`
LauraBeatris Aug 7, 2025
a4892f2
Introduce `onPendingSession` and remove `#componentNavigationContext`
LauraBeatris Aug 7, 2025
4a23f61
Remove redirect to task within `withRedirect` guard
LauraBeatris Aug 7, 2025
2500054
Navigate to tasks from sign up context
LauraBeatris Aug 7, 2025
5d39a6c
Remove `NavigateToTask` control component
LauraBeatris Aug 7, 2025
72108b2
Add redirect guards for root sign-in / sign-up AIOs
LauraBeatris Aug 8, 2025
4a09b4d
Use `taskUrl` from AIOs navigation
LauraBeatris Aug 8, 2025
3e54a20
Validate task options on Clerk init
LauraBeatris Aug 8, 2025
c87cca9
Adjust unit tests with newest API
LauraBeatris Aug 8, 2025
15baab2
Remove `#handlePendingSession` branch and introduce `navigate` option
nikosdouvlis Aug 8, 2025
fb0b6f0
Replace `onPendingSession` with `navigate`
LauraBeatris Aug 8, 2025
dd5a3c5
Add unit tests for invalidation hooks
LauraBeatris Aug 8, 2025
250ded9
Fix display name of redirect guards
LauraBeatris Aug 8, 2025
3d4a2e4
Rename `navigateToTask` from `navigateIfTaskExists`
LauraBeatris Aug 8, 2025
af7a4c7
Add warning for missing params for task handling
LauraBeatris Aug 8, 2025
e189667
Fix navigation between sign-in/sign-up steps
LauraBeatris Aug 8, 2025
7486db5
Preserve `redirectUrl` on `taskUrl` for after sign-in/sign-up
LauraBeatris Aug 8, 2025
6184aab
Add changesets
LauraBeatris Aug 8, 2025
6feb7ea
Navigate to next task if any from AIOs
LauraBeatris Aug 8, 2025
83a60c9
Fix `warnMissingPendingTaskHandlers` call
LauraBeatris Aug 8, 2025
968a327
Add `@inline` to `SetActiveNavigate` type
LauraBeatris Aug 8, 2025
9bde4ec
Fix navigation on active sessions
LauraBeatris Aug 8, 2025
0279ddc
Fix mocking of `signedInSessions`
LauraBeatris Aug 8, 2025
9c42234
Update custom flow snippet from changeset
LauraBeatris Aug 8, 2025
8dfc782
Fix typedoc tests
LauraBeatris Aug 8, 2025
735fb72
Fix navigation for multi-session
LauraBeatris Aug 8, 2025
921f611
Use `navigate` for `setActive` on combined flow
LauraBeatris Aug 9, 2025
c0d8c27
Rename `RedirectToTask` control component to `RedirectToTasks`
LauraBeatris Aug 9, 2025
cf7f966
Fix E2E test for sign-up with tasks
LauraBeatris Aug 9, 2025
cb553fe
Display root sign-in for multi-session mode with tasks
LauraBeatris Aug 9, 2025
7e590ff
Fix navigating to tasks on SSO callback
LauraBeatris Aug 9, 2025
5356efe
Bump max size of `clerk.headless` bundle
LauraBeatris Aug 9, 2025
17e01a4
Remove condition to always send `redirect_url` for SSO with after-aut…
LauraBeatris Aug 11, 2025
4142162
Remove duplicated changeset
LauraBeatris Aug 11, 2025
2171310
Remove `SessionTasksContext` from `TaskChooseOrganization`
LauraBeatris Aug 11, 2025
a9ec4dd
Fix `redirectUrl` for SSO with SignIn
LauraBeatris Aug 11, 2025
8626d49
Run `onAfterSetActive` if the new session is `active`
LauraBeatris Aug 11, 2025
e1e3628
Always use the latest session for status checks
nikosdouvlis Aug 11, 2025
508f7e0
Fix early returns in setActive
nikosdouvlis Aug 11, 2025
e800a1d
Fix session status check within `setActive`
LauraBeatris Aug 12, 2025
f492e9a
Maintain base URL of sign-in/sign-up for routing
LauraBeatris Aug 12, 2025
5ad3f51
Fix navigation for SSO to maintain path and hash routing
LauraBeatris Aug 12, 2025
a85cecd
Fix `RedirectToTasks` to only redirect to tasks
LauraBeatris Aug 13, 2025
1921845
Fix navigation for combined flow
LauraBeatris Aug 13, 2025
2de7d6e
Fix changeset
LauraBeatris Aug 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .changeset/rich-donuts-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@clerk/clerk-js': minor
'@clerk/types': minor
---

Add `navigate` parameter to `clerk.setActive()` for custom navigation before the session and/or organization is set.

It's useful for handling pending session tasks for after-auth flows:

```typescript
await clerk.setActive({
session,
navigate: async ({ session }) => {
const currentTask = session.currentTask;
if (currentTask) {
await router.push(`/onboarding/${currentTask.key}`)
return;
}

await router.push('/dashboard')
}
});
```
10 changes: 10 additions & 0 deletions .changeset/warm-rocks-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@clerk/tanstack-react-start': minor
'@clerk/react-router': minor
'@clerk/nextjs': minor
'@clerk/clerk-react': minor
'@clerk/remix': minor
'@clerk/vue': minor
---

Rename `RedirectToTask` control component to `RedirectToTasks`
2 changes: 1 addition & 1 deletion integration/tests/session-tasks-sign-in.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })(
await u.po.signIn.enterTestOtpCode();

// Resolves task
await u.po.signIn.waitForMounted();
await u.po.signUp.waitForMounted();
const fakeOrganization = Object.assign(u.services.organizations.createFakeOrganization(), {
slug: u.services.organizations.createFakeOrganization().slug + '-with-sign-in-sso',
});
Expand Down
32 changes: 25 additions & 7 deletions integration/tests/session-tasks-sign-up.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import { createClerkClient } from '@clerk/backend';
import { expect, test } from '@playwright/test';

import { appConfigs } from '../presets';
import { instanceKeys } from '../presets/envs';
import type { FakeUser } from '../testUtils';
import { createTestUtils, testAgainstRunningApps } from '../testUtils';
import { createUserService } from '../testUtils/usersService';

testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })(
'session tasks after sign-up flow @nextjs',
({ app }) => {
test.describe.configure({ mode: 'serial' });

let fakeUser: FakeUser;
let regularFakeUser: FakeUser;
let fakeUserForOAuth: FakeUser;

test.beforeEach(() => {
const u = createTestUtils({ app });
fakeUser = u.services.users.createFakeUser({
regularFakeUser = u.services.users.createFakeUser({
fictionalEmail: true,
withPhoneNumber: true,
withUsername: true,
});
fakeUserForOAuth = u.services.users.createFakeUser({
fictionalEmail: true,
withPhoneNumber: true,
withUsername: true,
Expand All @@ -23,7 +32,16 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })(
test.afterAll(async () => {
const u = createTestUtils({ app });
await u.services.organizations.deleteAll();
await fakeUser.deleteIfExists();
await regularFakeUser.deleteIfExists();

// Delete user from OAuth provider instance
const client = createClerkClient({
secretKey: instanceKeys.get('oauth-provider').sk,
publishableKey: instanceKeys.get('oauth-provider').pk,
});
const users = createUserService(client);
await users.deleteIfExists({ email: fakeUserForOAuth.email });

await app.teardown();
});

Expand All @@ -38,8 +56,8 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })(
const u = createTestUtils({ app, page, context });
await u.po.signUp.goTo();
await u.po.signUp.signUpWithEmailAndPassword({
email: fakeUser.email,
password: fakeUser.password,
email: regularFakeUser.email,
password: regularFakeUser.password,
});
await u.po.expect.toBeSignedIn();

Expand Down Expand Up @@ -68,12 +86,12 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })(
await u.po.signIn.getGoToSignUp().click();

await u.po.signUp.waitForMounted();
await u.po.signUp.setEmailAddress(fakeUser.email);
await u.po.signUp.setEmailAddress(fakeUserForOAuth.email);
await u.po.signUp.continue();
await u.po.signUp.enterTestOtpCode();

// Resolves task
await u.po.signIn.waitForMounted();
await u.po.signUp.waitForMounted();
const fakeOrganization = Object.assign(u.services.organizations.createFakeOrganization(), {
slug: u.services.organizations.createFakeOrganization().slug + '-with-sign-in-sso',
});
Expand Down
6 changes: 3 additions & 3 deletions packages/clerk-js/bundlewatch.config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"files": [
{ "path": "./dist/clerk.js", "maxSize": "622.25KB" },
{ "path": "./dist/clerk.browser.js", "maxSize": "76KB" },
{ "path": "./dist/clerk.js", "maxSize": "625KB" },
{ "path": "./dist/clerk.browser.js", "maxSize": "78KB" },
{ "path": "./dist/clerk.legacy.browser.js", "maxSize": "117KB" },
{ "path": "./dist/clerk.headless*.js", "maxSize": "58KB" },
{ "path": "./dist/clerk.headless*.js", "maxSize": "61KB" },
{ "path": "./dist/ui-common*.js", "maxSize": "113KB" },
{ "path": "./dist/ui-common*.legacy.*.js", "maxSize": "118KB" },
{ "path": "./dist/vendors*.js", "maxSize": "40.2KB" },
Expand Down
Loading
Loading