From 9fc30a8eb8779c5f6929d69be56d028b033c9e01 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Fri, 21 Mar 2025 18:51:50 -0300
Subject: [PATCH 1/7] Remove `experimental` flag with routing refactoring
---
.../next-app-router/src/app/layout.tsx | 2 -
packages/clerk-js/src/core/clerk.ts | 4 +-
packages/clerk-js/src/core/sessionTasks.ts | 6 +--
.../src/ui/components/SessionTask/index.ts | 1 -
.../SessionTasks.tsx} | 47 +++++++++----------
.../src/ui/components/SessionTasks/index.ts | 1 +
.../src/ui/components/SignIn/SignIn.tsx | 32 +++++--------
.../src/ui/components/SignUp/SignUp.tsx | 19 ++------
.../src/ui/contexts/components/SignIn.ts | 2 -
.../src/ui/contexts/components/SignUp.ts | 2 -
.../clerk-js/src/ui/lazyModules/components.ts | 8 ++--
packages/types/src/clerk.ts | 2 -
12 files changed, 49 insertions(+), 77 deletions(-)
delete mode 100644 packages/clerk-js/src/ui/components/SessionTask/index.ts
rename packages/clerk-js/src/ui/components/{SessionTask/SessionTask.tsx => SessionTasks/SessionTasks.tsx} (50%)
create mode 100644 packages/clerk-js/src/ui/components/SessionTasks/index.ts
diff --git a/integration/templates/next-app-router/src/app/layout.tsx b/integration/templates/next-app-router/src/app/layout.tsx
index e598334db2..2e56184f39 100644
--- a/integration/templates/next-app-router/src/app/layout.tsx
+++ b/integration/templates/next-app-router/src/app/layout.tsx
@@ -24,8 +24,6 @@ export default function RootLayout({ children }: { children: React.ReactNode })
persistClient: process.env.NEXT_PUBLIC_EXPERIMENTAL_PERSIST_CLIENT
? process.env.NEXT_PUBLIC_EXPERIMENTAL_PERSIST_CLIENT === 'true'
: undefined,
- // `experimental.withSessionTasks` will be removed soon in favor of checking via environment response
- withSessionTasks: true,
}}
>
diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts
index 65cd4c2e92..b1c129f43e 100644
--- a/packages/clerk-js/src/core/clerk.ts
+++ b/packages/clerk-js/src/core/clerk.ts
@@ -1086,7 +1086,7 @@ export class Clerk implements ClerkInterface {
}
if (newSession?.currentTask) {
- await navigateToTask(session.currentTask, {
+ await navigateToTask(session.currentTask.key, {
globalNavigate: this.navigate,
componentNavigationContext: this.#componentNavigationContext,
options: this.#options,
@@ -1109,7 +1109,7 @@ export class Clerk implements ClerkInterface {
}
if (session.status === 'pending') {
- await navigateToTask(session.currentTask, {
+ await navigateToTask(session.currentTask.key, {
options: this.#options,
environment: this.environment,
globalNavigate: this.navigate,
diff --git a/packages/clerk-js/src/core/sessionTasks.ts b/packages/clerk-js/src/core/sessionTasks.ts
index aeef4fc5b8..f620508a50 100644
--- a/packages/clerk-js/src/core/sessionTasks.ts
+++ b/packages/clerk-js/src/core/sessionTasks.ts
@@ -24,13 +24,13 @@ interface NavigateToTaskOptions {
* @internal
*/
export function navigateToTask(
- task: SessionTask,
+ routeKey: keyof typeof SESSION_TASK_ROUTE_BY_KEY,
{ componentNavigationContext, globalNavigate, options, environment }: NavigateToTaskOptions,
) {
- const taskRoute = `/${SESSION_TASK_ROUTE_BY_KEY[task.key]}`;
+ const taskRoute = `/${SESSION_TASK_ROUTE_BY_KEY[routeKey]}`;
if (componentNavigationContext) {
- return componentNavigationContext.navigate(componentNavigationContext.indexPath + taskRoute);
+ return componentNavigationContext.navigate(componentNavigationContext.indexPath + routeKey);
}
const signInUrl = options['signInUrl'] || environment.displayConfig.signInUrl;
diff --git a/packages/clerk-js/src/ui/components/SessionTask/index.ts b/packages/clerk-js/src/ui/components/SessionTask/index.ts
deleted file mode 100644
index ddae613a6e..0000000000
--- a/packages/clerk-js/src/ui/components/SessionTask/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './SessionTask';
diff --git a/packages/clerk-js/src/ui/components/SessionTask/SessionTask.tsx b/packages/clerk-js/src/ui/components/SessionTasks/SessionTasks.tsx
similarity index 50%
rename from packages/clerk-js/src/ui/components/SessionTask/SessionTask.tsx
rename to packages/clerk-js/src/ui/components/SessionTasks/SessionTasks.tsx
index 03710860ed..6ef656357f 100644
--- a/packages/clerk-js/src/ui/components/SessionTask/SessionTask.tsx
+++ b/packages/clerk-js/src/ui/components/SessionTasks/SessionTasks.tsx
@@ -3,36 +3,39 @@ import { eventComponentMounted } from '@clerk/shared/telemetry';
import type { SessionTask } from '@clerk/types';
import { useCallback, useEffect } from 'react';
+import { SESSION_TASK_ROUTE_BY_KEY } from '../../../core/sessionTasks';
import { OrganizationListContext } from '../../contexts';
import { SessionTaskContext as SessionTaskContext } from '../../contexts/components/SessionTask';
-import { useRouter } from '../../router';
+import { Route, Switch, useRouter } from '../../router';
import { OrganizationList } from '../OrganizationList';
-interface SessionTaskProps {
- task: SessionTask['key'];
- redirectUrlComplete: string;
+// TODO -> Lazy load individual routes per environment config
+function SessionTaskRoutes(): JSX.Element {
+ return (
+
+
+
+
+
+
+
+ );
}
-const ContentRegistry: Record = {
- org: () => (
-
-
-
- ),
-};
-
/**
* @internal
*/
-export function SessionTask({ task, redirectUrlComplete }: SessionTaskProps): React.ReactNode {
- const { session, telemetry, __experimental_nextTask } = useClerk();
+export function SessionTask({ redirectUrlComplete }: { redirectUrlComplete: string }): JSX.Element {
+ const { __experimental_nextTask, session, telemetry } = useClerk();
const { navigate } = useRouter();
+ telemetry?.record(eventComponentMounted('SessionTask', { task: session?.currentTask?.key as string }));
+
useEffect(() => {
if (session?.currentTask) {
return;
@@ -41,18 +44,14 @@ export function SessionTask({ task, redirectUrlComplete }: SessionTaskProps): Re
void navigate(redirectUrlComplete);
}, [session?.currentTask, navigate, redirectUrlComplete]);
- telemetry?.record(eventComponentMounted('SessionTask', { task }));
-
const nextTask = useCallback(
() => __experimental_nextTask({ redirectUrlComplete }),
[__experimental_nextTask, redirectUrlComplete],
);
- const Content = ContentRegistry[task];
-
return (
-
+
);
}
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/index.ts b/packages/clerk-js/src/ui/components/SessionTasks/index.ts
new file mode 100644
index 0000000000..f5840ac701
--- /dev/null
+++ b/packages/clerk-js/src/ui/components/SessionTasks/index.ts
@@ -0,0 +1 @@
+export * from './SessionTasks';
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
index 08416ec915..1bede25f8f 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
@@ -15,7 +15,7 @@ import {
} from '../../contexts';
import { Flow } from '../../customizables';
import { useFetch } from '../../hooks';
-import { preloadSessionTask, SessionTask } from '../../lazyModules/components';
+import { preloadSessionTasks, SessionTasks } from '../../lazyModules/components';
import { Route, Switch, useRouter, VIRTUAL_ROUTER_BASE_PATH } from '../../router';
import {
LazySignUpContinue,
@@ -130,14 +130,12 @@ function SignInRoutes(): JSX.Element {
>
- {signInContext.withSessionTasks && (
-
-
-
- )}
+
+
+
@@ -147,14 +145,9 @@ function SignInRoutes(): JSX.Element {
)}
- {signInContext.withSessionTasks && (
-
-
-
- )}
+
+
+
@@ -170,7 +163,7 @@ const usePreloadSignUp = (enabled = false) =>
useFetch(enabled ? preloadSignUp : undefined, 'preloadComponent', { staleTime: Infinity });
const usePreloadSessionTask = (enabled = false) =>
- useFetch(enabled ? preloadSessionTask : undefined, 'preloadComponent', { staleTime: Infinity });
+ useFetch(enabled ? preloadSessionTasks : undefined, 'preloadComponent', { staleTime: Infinity });
function SignInRoot() {
const { __internal_setComponentNavigationContext } = useClerk();
@@ -193,9 +186,6 @@ function SignInRoot() {
*/
usePreloadSignUp(signInContext.isCombinedFlow);
- // `experimental.withSessionTasks` will be removed soon in favor of checking via environment response
- usePreloadSessionTask(signInContext.withSessionTasks);
-
React.useEffect(() => {
return __internal_setComponentNavigationContext?.({ indexPath, navigate });
}, [indexPath, navigate]);
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
index b883386727..283a8b8018 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
@@ -2,12 +2,11 @@ import { useClerk } from '@clerk/shared/react';
import type { SignUpModalProps, SignUpProps } from '@clerk/types';
import React from 'react';
-import { SESSION_TASK_ROUTE_BY_KEY } from '../../../core/sessionTasks';
import { SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import { SignUpContext, useSignUpContext, withCoreSessionSwitchGuard } from '../../contexts';
import { Flow } from '../../customizables';
import { useFetch } from '../../hooks';
-import { preloadSessionTask, SessionTask } from '../../lazyModules/components';
+import { preloadSessionTasks, SessionTasks } from '../../lazyModules/components';
import { Route, Switch, useRouter, VIRTUAL_ROUTER_BASE_PATH } from '../../router';
import { SignUpContinue } from './SignUpContinue';
import { SignUpSSOCallback } from './SignUpSSOCallback';
@@ -16,7 +15,7 @@ import { SignUpVerifyEmail } from './SignUpVerifyEmail';
import { SignUpVerifyPhone } from './SignUpVerifyPhone';
const usePreloadSessionTask = (enabled = false) =>
- useFetch(enabled ? preloadSessionTask : undefined, 'preloadComponent', { staleTime: Infinity });
+ useFetch(enabled ? preloadSessionTasks : undefined, 'preloadComponent', { staleTime: Infinity });
function RedirectToSignUp() {
const clerk = useClerk();
@@ -31,9 +30,6 @@ function SignUpRoutes(): JSX.Element {
const { navigate, indexPath } = useRouter();
const signUpContext = useSignUpContext();
- // `experimental.withSessionTasks` will be removed soon in favor of checking via environment response
- usePreloadSessionTask(signUpContext.withSessionTasks);
-
React.useEffect(() => {
return __internal_setComponentNavigationContext?.({ indexPath, navigate });
}, [indexPath, navigate]);
@@ -89,14 +85,9 @@ function SignUpRoutes(): JSX.Element {
- {signUpContext.withSessionTasks && (
-
-
-
- )}
+
+
+
diff --git a/packages/clerk-js/src/ui/contexts/components/SignIn.ts b/packages/clerk-js/src/ui/contexts/components/SignIn.ts
index 3d5e77f50d..aa6603ce78 100644
--- a/packages/clerk-js/src/ui/contexts/components/SignIn.ts
+++ b/packages/clerk-js/src/ui/contexts/components/SignIn.ts
@@ -32,7 +32,6 @@ export type SignInContextType = SignInCtx & {
emailLinkRedirectUrl: string;
ssoCallbackUrl: string;
isCombinedFlow: boolean;
- withSessionTasks: boolean;
};
export const SignInContext = createContext(null);
@@ -145,6 +144,5 @@ export const useSignInContext = (): SignInContextType => {
initialValues: { ...ctx.initialValues, ...initialValuesFromQueryParams },
authQueryString,
isCombinedFlow,
- withSessionTasks: !!options.experimental?.withSessionTasks,
};
};
diff --git a/packages/clerk-js/src/ui/contexts/components/SignUp.ts b/packages/clerk-js/src/ui/contexts/components/SignUp.ts
index 7d1d58f6f8..5f9be1727a 100644
--- a/packages/clerk-js/src/ui/contexts/components/SignUp.ts
+++ b/packages/clerk-js/src/ui/contexts/components/SignUp.ts
@@ -31,7 +31,6 @@ export type SignUpContextType = SignUpCtx & {
isCombinedFlow: boolean;
emailLinkRedirectUrl: string;
ssoCallbackUrl: string;
- withSessionTasks: boolean;
};
export const SignUpContext = createContext(null);
@@ -139,6 +138,5 @@ export const useSignUpContext = (): SignUpContextType => {
initialValues: { ...ctx.initialValues, ...initialValuesFromQueryParams },
authQueryString,
isCombinedFlow,
- withSessionTasks: !!options.experimental?.withSessionTasks,
};
};
diff --git a/packages/clerk-js/src/ui/lazyModules/components.ts b/packages/clerk-js/src/ui/lazyModules/components.ts
index 6182576c71..d48c29e941 100644
--- a/packages/clerk-js/src/ui/lazyModules/components.ts
+++ b/packages/clerk-js/src/ui/lazyModules/components.ts
@@ -19,7 +19,7 @@ const componentImportPaths = {
KeylessPrompt: () => import(/* webpackChunkName: "keylessPrompt" */ '../components/KeylessPrompt'),
PricingTable: () => import(/* webpackChunkName: "pricingTable" */ '../components/PricingTable'),
Checkout: () => import(/* webpackChunkName: "checkout" */ '../components/Checkout'),
- SessionTask: () => import(/* webpackChunkName: "sessionTask" */ '../components/SessionTask'),
+ SessionTasks: () => import(/* webpackChunkName: "sessionTasks" */ '../components/SessionTasks'),
} as const;
export const SignIn = lazy(() => componentImportPaths.SignIn().then(module => ({ default: module.SignIn })));
@@ -95,9 +95,9 @@ export const PricingTable = lazy(() =>
componentImportPaths.PricingTable().then(module => ({ default: module.__experimental_PricingTable })),
);
-export const preloadSessionTask = () => import(/* webpackChunkName: "sessionTask" */ '../components/SessionTask');
-export const SessionTask = lazy(() =>
- componentImportPaths.SessionTask().then(module => ({ default: module.SessionTask })),
+export const preloadSessionTasks = () => import(/* webpackChunkName: "sessionTasks" */ '../components/SessionTasks');
+export const SessionTasks = lazy(() =>
+ componentImportPaths.SessionTasks().then(module => ({ default: module.SessionTask })),
);
export const preloadComponent = async (component: unknown) => {
diff --git a/packages/types/src/clerk.ts b/packages/types/src/clerk.ts
index ff19882dd3..5ff1e100ad 100644
--- a/packages/types/src/clerk.ts
+++ b/packages/types/src/clerk.ts
@@ -821,8 +821,6 @@ export type ClerkOptions = ClerkOptionsNavigation &
*/
rethrowOfflineNetworkErrors: boolean;
commerce: boolean;
- // `experimental.withSessionTasks` will be removed soon in favor of checking via environment response
- withSessionTasks: boolean;
},
Record
>;
From cd1f130e48465d3724fd88b3b5d5da2e17a7f506 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Fri, 21 Mar 2025 19:12:10 -0300
Subject: [PATCH 2/7] Extract tasks under `/tasks` root path
---
.../SessionTasks/OrganizationSelectionTask.tsx | 18 ++++++++++++++++++
.../src/ui/components/SessionTasks/index.ts | 1 -
.../{SessionTasks.tsx => index.tsx} | 15 ++++-----------
.../SessionTasks/lazySessionTasks.ts | 12 ++++++++++++
.../components/SessionTasks/usePreloadTasks.ts | 14 ++++++++++++++
.../src/ui/components/SignIn/SignIn.tsx | 13 +++----------
.../src/ui/components/SignUp/SignUp.tsx | 6 +-----
7 files changed, 52 insertions(+), 27 deletions(-)
create mode 100644 packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx
delete mode 100644 packages/clerk-js/src/ui/components/SessionTasks/index.ts
rename packages/clerk-js/src/ui/components/SessionTasks/{SessionTasks.tsx => index.tsx} (76%)
create mode 100644 packages/clerk-js/src/ui/components/SessionTasks/lazySessionTasks.ts
create mode 100644 packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx b/packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx
new file mode 100644
index 0000000000..2022e3b69b
--- /dev/null
+++ b/packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx
@@ -0,0 +1,18 @@
+import { OrganizationListContext } from '../../contexts';
+import { OrganizationList } from '../OrganizationList';
+
+/**
+ * @internal
+ */
+export function OrganizationSelectionTask() {
+ return (
+
+
+
+ );
+}
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/index.ts b/packages/clerk-js/src/ui/components/SessionTasks/index.ts
deleted file mode 100644
index f5840ac701..0000000000
--- a/packages/clerk-js/src/ui/components/SessionTasks/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './SessionTasks';
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/SessionTasks.tsx b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
similarity index 76%
rename from packages/clerk-js/src/ui/components/SessionTasks/SessionTasks.tsx
rename to packages/clerk-js/src/ui/components/SessionTasks/index.tsx
index 6ef656357f..3f732effd7 100644
--- a/packages/clerk-js/src/ui/components/SessionTasks/SessionTasks.tsx
+++ b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
@@ -4,24 +4,16 @@ import type { SessionTask } from '@clerk/types';
import { useCallback, useEffect } from 'react';
import { SESSION_TASK_ROUTE_BY_KEY } from '../../../core/sessionTasks';
-import { OrganizationListContext } from '../../contexts';
import { SessionTaskContext as SessionTaskContext } from '../../contexts/components/SessionTask';
import { Route, Switch, useRouter } from '../../router';
-import { OrganizationList } from '../OrganizationList';
+import { LazyOrganizationSelectionTask } from './lazySessionTasks';
+import { usePreloadTasks } from './usePreloadTasks';
-// TODO -> Lazy load individual routes per environment config
function SessionTaskRoutes(): JSX.Element {
return (
-
-
-
+
);
@@ -31,6 +23,7 @@ function SessionTaskRoutes(): JSX.Element {
* @internal
*/
export function SessionTask({ redirectUrlComplete }: { redirectUrlComplete: string }): JSX.Element {
+ usePreloadTasks();
const { __experimental_nextTask, session, telemetry } = useClerk();
const { navigate } = useRouter();
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/lazySessionTasks.ts b/packages/clerk-js/src/ui/components/SessionTasks/lazySessionTasks.ts
new file mode 100644
index 0000000000..75eb431c8e
--- /dev/null
+++ b/packages/clerk-js/src/ui/components/SessionTasks/lazySessionTasks.ts
@@ -0,0 +1,12 @@
+import { lazy } from 'react';
+
+export const preloadOrganizationSelectionTask = () =>
+ import(/* webpackChunkName: "session-tasks"*/ './OrganizationSelectionTask');
+
+const LazyOrganizationSelectionTask = lazy(() =>
+ import(/* webpackChunkName: "session-tasks"*/ './OrganizationSelectionTask').then(module => ({
+ default: module.OrganizationSelectionTask,
+ })),
+);
+
+export { LazyOrganizationSelectionTask };
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts b/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
new file mode 100644
index 0000000000..4b9626094d
--- /dev/null
+++ b/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
@@ -0,0 +1,14 @@
+import { useEnvironment } from '../../../ui/contexts';
+import { preloadOrganizationSelectionTask } from './lazySessionTasks';
+
+/**
+ * Preloads tasks based on the environment settings
+ * @internal
+ */
+export function usePreloadTasks() {
+ const { organizationSettings } = useEnvironment();
+
+ if (organizationSettings.forceOrganizationSelection) {
+ void preloadOrganizationSelectionTask();
+ }
+}
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
index 1bede25f8f..0e6b2f5e5f 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
@@ -2,7 +2,6 @@ import { useClerk } from '@clerk/shared/react';
import type { SignInModalProps, SignInProps } from '@clerk/types';
import React from 'react';
-import { SESSION_TASK_ROUTE_BY_KEY } from '../../../core/sessionTasks';
import { normalizeRoutingOptions } from '../../../utils/normalizeRoutingOptions';
import { SignInEmailLinkFlowComplete, SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import type { SignUpContextType } from '../../contexts';
@@ -15,7 +14,7 @@ import {
} from '../../contexts';
import { Flow } from '../../customizables';
import { useFetch } from '../../hooks';
-import { preloadSessionTasks, SessionTasks } from '../../lazyModules/components';
+import { SessionTasks } from '../../lazyModules/components';
import { Route, Switch, useRouter, VIRTUAL_ROUTER_BASE_PATH } from '../../router';
import {
LazySignUpContinue,
@@ -130,11 +129,8 @@ function SignInRoutes(): JSX.Element {
>
-
-
+
+
@@ -162,9 +158,6 @@ function SignInRoutes(): JSX.Element {
const usePreloadSignUp = (enabled = false) =>
useFetch(enabled ? preloadSignUp : undefined, 'preloadComponent', { staleTime: Infinity });
-const usePreloadSessionTask = (enabled = false) =>
- useFetch(enabled ? preloadSessionTasks : undefined, 'preloadComponent', { staleTime: Infinity });
-
function SignInRoot() {
const { __internal_setComponentNavigationContext } = useClerk();
const { navigate, indexPath } = useRouter();
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
index 283a8b8018..c928c39a0e 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
@@ -5,8 +5,7 @@ import React from 'react';
import { SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import { SignUpContext, useSignUpContext, withCoreSessionSwitchGuard } from '../../contexts';
import { Flow } from '../../customizables';
-import { useFetch } from '../../hooks';
-import { preloadSessionTasks, SessionTasks } from '../../lazyModules/components';
+import { SessionTasks } from '../../lazyModules/components';
import { Route, Switch, useRouter, VIRTUAL_ROUTER_BASE_PATH } from '../../router';
import { SignUpContinue } from './SignUpContinue';
import { SignUpSSOCallback } from './SignUpSSOCallback';
@@ -14,9 +13,6 @@ import { SignUpStart } from './SignUpStart';
import { SignUpVerifyEmail } from './SignUpVerifyEmail';
import { SignUpVerifyPhone } from './SignUpVerifyPhone';
-const usePreloadSessionTask = (enabled = false) =>
- useFetch(enabled ? preloadSessionTasks : undefined, 'preloadComponent', { staleTime: Infinity });
-
function RedirectToSignUp() {
const clerk = useClerk();
React.useEffect(() => {
From 0ca95f9484f96c2c7b8b5a3001ae37ed7ab72397 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Fri, 21 Mar 2025 19:16:01 -0300
Subject: [PATCH 3/7] Introduce bundle on `bundlewatch`
---
packages/clerk-js/bundlewatch.config.json | 3 ++-
packages/clerk-js/src/core/sessionTasks.ts | 2 +-
packages/clerk-js/src/ui/common/redirects.ts | 3 +--
.../clerk-js/src/ui/components/SessionTasks/index.tsx | 10 ++++++----
.../SessionTasks/{lazySessionTasks.ts => lazyTasks.ts} | 2 +-
.../src/ui/components/SessionTasks/usePreloadTasks.ts | 5 +++--
6 files changed, 14 insertions(+), 11 deletions(-)
rename packages/clerk-js/src/ui/components/SessionTasks/{lazySessionTasks.ts => lazyTasks.ts} (80%)
diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json
index 659c6c18e7..8c26334f24 100644
--- a/packages/clerk-js/bundlewatch.config.json
+++ b/packages/clerk-js/bundlewatch.config.json
@@ -21,6 +21,7 @@
{ "path": "./dist/keylessPrompt*.js", "maxSize": "5.9KB" },
{ "path": "./dist/pricingTable*.js", "maxSize": "5KB" },
{ "path": "./dist/checkout*.js", "maxSize": "9KB" },
- { "path": "./dist/up-billing-page*.js", "maxSize": "1KB" }
+ { "path": "./dist/up-billing-page*.js", "maxSize": "1KB" },
+ { "path": "./dist/session-tasks*.js", "maxSize": "1KB" }
]
}
diff --git a/packages/clerk-js/src/core/sessionTasks.ts b/packages/clerk-js/src/core/sessionTasks.ts
index f620508a50..ff0bb13b45 100644
--- a/packages/clerk-js/src/core/sessionTasks.ts
+++ b/packages/clerk-js/src/core/sessionTasks.ts
@@ -27,7 +27,7 @@ export function navigateToTask(
routeKey: keyof typeof SESSION_TASK_ROUTE_BY_KEY,
{ componentNavigationContext, globalNavigate, options, environment }: NavigateToTaskOptions,
) {
- const taskRoute = `/${SESSION_TASK_ROUTE_BY_KEY[routeKey]}`;
+ const taskRoute = `/tasks/${SESSION_TASK_ROUTE_BY_KEY[routeKey]}`;
if (componentNavigationContext) {
return componentNavigationContext.navigate(componentNavigationContext.indexPath + routeKey);
diff --git a/packages/clerk-js/src/ui/common/redirects.ts b/packages/clerk-js/src/ui/common/redirects.ts
index 6b785c9d69..763809bc7d 100644
--- a/packages/clerk-js/src/ui/common/redirects.ts
+++ b/packages/clerk-js/src/ui/common/redirects.ts
@@ -1,6 +1,5 @@
import type { SessionTask } from '@clerk/types';
-import { SESSION_TASK_ROUTE_BY_KEY } from '../../core/sessionTasks';
import { buildURL } from '../../utils/url';
import type { SignInContextType, SignUpContextType, UserProfileContextType } from './../contexts';
@@ -45,7 +44,7 @@ export function buildSessionTaskRedirectUrl({
routing,
baseUrl,
path,
- endpoint: `/${SESSION_TASK_ROUTE_BY_KEY[task.key]}`,
+ endpoint: '/tasks',
authQueryString: null,
});
}
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/index.tsx b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
index 3f732effd7..227b4a050c 100644
--- a/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
+++ b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
@@ -6,7 +6,7 @@ import { useCallback, useEffect } from 'react';
import { SESSION_TASK_ROUTE_BY_KEY } from '../../../core/sessionTasks';
import { SessionTaskContext as SessionTaskContext } from '../../contexts/components/SessionTask';
import { Route, Switch, useRouter } from '../../router';
-import { LazyOrganizationSelectionTask } from './lazySessionTasks';
+import { LazyOrganizationSelectionTask } from './lazyTasks';
import { usePreloadTasks } from './usePreloadTasks';
function SessionTaskRoutes(): JSX.Element {
@@ -24,18 +24,20 @@ function SessionTaskRoutes(): JSX.Element {
*/
export function SessionTask({ redirectUrlComplete }: { redirectUrlComplete: string }): JSX.Element {
usePreloadTasks();
+
const { __experimental_nextTask, session, telemetry } = useClerk();
const { navigate } = useRouter();
- telemetry?.record(eventComponentMounted('SessionTask', { task: session?.currentTask?.key as string }));
+ const task = session?.currentTask;
useEffect(() => {
- if (session?.currentTask) {
+ if (task) {
+ telemetry?.record(eventComponentMounted('SessionTask', { task: task.key }));
return;
}
void navigate(redirectUrlComplete);
- }, [session?.currentTask, navigate, redirectUrlComplete]);
+ }, [task, telemetry, navigate, redirectUrlComplete]);
const nextTask = useCallback(
() => __experimental_nextTask({ redirectUrlComplete }),
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/lazySessionTasks.ts b/packages/clerk-js/src/ui/components/SessionTasks/lazyTasks.ts
similarity index 80%
rename from packages/clerk-js/src/ui/components/SessionTasks/lazySessionTasks.ts
rename to packages/clerk-js/src/ui/components/SessionTasks/lazyTasks.ts
index 75eb431c8e..990e47b4d9 100644
--- a/packages/clerk-js/src/ui/components/SessionTasks/lazySessionTasks.ts
+++ b/packages/clerk-js/src/ui/components/SessionTasks/lazyTasks.ts
@@ -1,7 +1,7 @@
import { lazy } from 'react';
export const preloadOrganizationSelectionTask = () =>
- import(/* webpackChunkName: "session-tasks"*/ './OrganizationSelectionTask');
+ import(/* webpackChunkName: "session-tasks"*/ './OrganizationSelectionTask');
const LazyOrganizationSelectionTask = lazy(() =>
import(/* webpackChunkName: "session-tasks"*/ './OrganizationSelectionTask').then(module => ({
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts b/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
index 4b9626094d..b9c46279e6 100644
--- a/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
+++ b/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
@@ -1,5 +1,6 @@
import { useEnvironment } from '../../../ui/contexts';
-import { preloadOrganizationSelectionTask } from './lazySessionTasks';
+import { useFetch } from '../../../ui/hooks';
+import { preloadOrganizationSelectionTask } from './lazyTasks';
/**
* Preloads tasks based on the environment settings
@@ -9,6 +10,6 @@ export function usePreloadTasks() {
const { organizationSettings } = useEnvironment();
if (organizationSettings.forceOrganizationSelection) {
- void preloadOrganizationSelectionTask();
+ void useFetch(preloadOrganizationSelectionTask, 'preloadComponent', { staleTime: Infinity });
}
}
From 4abb96d90f5c32b3516f95ff64ab847f65018d33 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Sun, 23 Mar 2025 14:05:28 -0300
Subject: [PATCH 4/7] Introduce root route to resolve tasks
---
packages/clerk-js/bundlewatch.config.json | 2 +-
.../clerk-js/src/core/__tests__/clerk.test.ts | 8 +-
packages/clerk-js/src/core/sessionTasks.ts | 2 +-
packages/clerk-js/src/ui/common/redirects.ts | 3 +-
.../OrganizationList/OrganizationListPage.tsx | 8 +-
.../OrganizationList/UserMembershipList.tsx | 8 +-
.../OrganizationSelectionTask.tsx | 18 -----
.../src/ui/components/SessionTasks/index.tsx | 78 ++++++++++++++-----
.../ui/components/SessionTasks/lazyTasks.ts | 12 ---
.../SessionTasks/usePreloadTasks.ts | 15 ----
.../src/ui/components/SignIn/SignIn.tsx | 9 ++-
.../src/ui/components/SignUp/SignUp.tsx | 7 +-
.../src/ui/contexts/components/SessionTask.ts | 5 --
.../ui/contexts/components/SessionTasks.ts | 5 ++
.../clerk-js/src/ui/hooks/usePreloadTasks.ts | 20 +++++
.../clerk-js/src/ui/lazyModules/components.ts | 1 -
packages/clerk-js/src/ui/types.ts | 4 +-
.../clerk-js/src/utils/componentGuards.ts | 4 +
18 files changed, 119 insertions(+), 90 deletions(-)
delete mode 100644 packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx
delete mode 100644 packages/clerk-js/src/ui/components/SessionTasks/lazyTasks.ts
delete mode 100644 packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
delete mode 100644 packages/clerk-js/src/ui/contexts/components/SessionTask.ts
create mode 100644 packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
create mode 100644 packages/clerk-js/src/ui/hooks/usePreloadTasks.ts
diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json
index 8c26334f24..6785631e12 100644
--- a/packages/clerk-js/bundlewatch.config.json
+++ b/packages/clerk-js/bundlewatch.config.json
@@ -22,6 +22,6 @@
{ "path": "./dist/pricingTable*.js", "maxSize": "5KB" },
{ "path": "./dist/checkout*.js", "maxSize": "9KB" },
{ "path": "./dist/up-billing-page*.js", "maxSize": "1KB" },
- { "path": "./dist/session-tasks*.js", "maxSize": "1KB" }
+ { "path": "./dist/sessionTasks*.js", "maxSize": "1KB" }
]
}
diff --git a/packages/clerk-js/src/core/__tests__/clerk.test.ts b/packages/clerk-js/src/core/__tests__/clerk.test.ts
index 50c34e563d..c2f550c3db 100644
--- a/packages/clerk-js/src/core/__tests__/clerk.test.ts
+++ b/packages/clerk-js/src/core/__tests__/clerk.test.ts
@@ -486,14 +486,14 @@ describe('Clerk singleton', () => {
getToken: jest.fn(),
lastActiveToken: { getRawString: () => 'mocked-token' },
tasks: [{ key: 'org' }],
- currentTask: { key: 'org', __internal_getUrl: () => 'https://foocorp.com/add-organization' },
+ currentTask: { key: 'org', __internal_getUrl: () => 'https://sut/tasks/add-organization' },
reload: jest.fn(() =>
Promise.resolve({
id: '1',
status: 'pending',
user: {},
tasks: [{ key: 'org' }],
- currentTask: { key: 'org', __internal_getUrl: () => 'https://foocorp.com/add-organization' },
+ currentTask: { key: 'org', __internal_getUrl: () => 'https://sut/tasks/add-organization' },
}),
),
};
@@ -2287,7 +2287,7 @@ describe('Clerk singleton', () => {
status: 'pending',
user: {},
tasks: [{ key: 'org' }],
- currentTask: { key: 'org', __internal_getUrl: () => 'https://foocorp.com/add-organization' },
+ currentTask: { key: 'org', __internal_getUrl: () => 'https://sut/tasks/add-organization' },
lastActiveToken: { getRawString: () => 'mocked-token' },
};
@@ -2316,7 +2316,7 @@ describe('Clerk singleton', () => {
await sut.setActive({ session: mockResource as any as PendingSessionResource });
await sut.__experimental_nextTask();
- expect(mockNavigate.mock.calls[0][0]).toBe('/sign-in#/add-organization');
+ expect(mockNavigate.mock.calls[0][0]).toBe('/sign-in#/tasks/add-organization');
});
});
diff --git a/packages/clerk-js/src/core/sessionTasks.ts b/packages/clerk-js/src/core/sessionTasks.ts
index ff0bb13b45..1971d68e87 100644
--- a/packages/clerk-js/src/core/sessionTasks.ts
+++ b/packages/clerk-js/src/core/sessionTasks.ts
@@ -30,7 +30,7 @@ export function navigateToTask(
const taskRoute = `/tasks/${SESSION_TASK_ROUTE_BY_KEY[routeKey]}`;
if (componentNavigationContext) {
- return componentNavigationContext.navigate(componentNavigationContext.indexPath + routeKey);
+ return componentNavigationContext.navigate(componentNavigationContext.indexPath + taskRoute);
}
const signInUrl = options['signInUrl'] || environment.displayConfig.signInUrl;
diff --git a/packages/clerk-js/src/ui/common/redirects.ts b/packages/clerk-js/src/ui/common/redirects.ts
index 763809bc7d..088a02a023 100644
--- a/packages/clerk-js/src/ui/common/redirects.ts
+++ b/packages/clerk-js/src/ui/common/redirects.ts
@@ -1,5 +1,6 @@
import type { SessionTask } from '@clerk/types';
+import { SESSION_TASK_ROUTE_BY_KEY } from '../../core/sessionTasks';
import { buildURL } from '../../utils/url';
import type { SignInContextType, SignUpContextType, UserProfileContextType } from './../contexts';
@@ -44,7 +45,7 @@ export function buildSessionTaskRedirectUrl({
routing,
baseUrl,
path,
- endpoint: '/tasks',
+ endpoint: `/tasks/${SESSION_TASK_ROUTE_BY_KEY[task.key]}`,
authQueryString: null,
});
}
diff --git a/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx b/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx
index d932090e52..4a5963fc20 100644
--- a/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx
+++ b/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx
@@ -2,7 +2,7 @@ import { useOrganizationList, useUser } from '@clerk/shared/react';
import { useContext, useState } from 'react';
import { useEnvironment, useOrganizationListContext } from '../../contexts';
-import { SessionTaskContext } from '../../contexts/components/SessionTask';
+import { SessionTasksContext } from '../../contexts/components/SessionTasks';
import { Box, Col, descriptors, Flex, localizationKeys, Spinner } from '../../customizables';
import { Action, Actions, Card, Header, useCardState, withCardStateProvider } from '../../elements';
import { useInView } from '../../hooks';
@@ -17,6 +17,8 @@ import { organizationListParams } from './utils';
const useOrganizationListInView = () => {
const { userMemberships, userInvitations, userSuggestions } = useOrganizationList(organizationListParams);
+ console.log({ userMemberships });
+
const { ref } = useInView({
threshold: 0,
onChange: inView => {
@@ -112,7 +114,7 @@ export const OrganizationListPage = withCardStateProvider(() => {
const OrganizationListFlows = ({ showListInitially }: { showListInitially: boolean }) => {
const { navigateAfterCreateOrganization, skipInvitationScreen, hideSlug } = useOrganizationListContext();
const [isCreateOrganizationFlow, setCreateOrganizationFlow] = useState(!showListInitially);
- const sessionTaskContext = useContext(SessionTaskContext);
+ const sessionTasksContext = useContext(SessionTasksContext);
return (
<>
{!isCreateOrganizationFlow && (
@@ -127,7 +129,7 @@ const OrganizationListFlows = ({ showListInitially }: { showListInitially: boole
>
diff --git a/packages/clerk-js/src/ui/components/OrganizationList/UserMembershipList.tsx b/packages/clerk-js/src/ui/components/OrganizationList/UserMembershipList.tsx
index fa4e36e73d..f2861af17a 100644
--- a/packages/clerk-js/src/ui/components/OrganizationList/UserMembershipList.tsx
+++ b/packages/clerk-js/src/ui/components/OrganizationList/UserMembershipList.tsx
@@ -3,7 +3,7 @@ import type { OrganizationResource } from '@clerk/types';
import { useContext } from 'react';
import { useOrganizationListContext } from '../../contexts';
-import { SessionTaskContext } from '../../contexts/components/SessionTask';
+import { SessionTasksContext } from '../../contexts/components/SessionTasks';
import { OrganizationPreview, PersonalWorkspacePreview, useCardState, withCardStateProvider } from '../../elements';
import { localizationKeys } from '../../localization';
import { OrganizationListPreviewButton, sharedMainIdentifierSx } from './shared';
@@ -12,7 +12,7 @@ export const MembershipPreview = withCardStateProvider((props: { organization: O
const card = useCardState();
const { navigateAfterSelectOrganization } = useOrganizationListContext();
const { isLoaded, setActive } = useOrganizationList();
- const sessionTaskContext = useContext(SessionTaskContext);
+ const sessionTasksContext = useContext(SessionTasksContext);
if (!isLoaded) {
return null;
@@ -23,8 +23,8 @@ export const MembershipPreview = withCardStateProvider((props: { organization: O
organization,
});
- if (sessionTaskContext?.nextTask) {
- return sessionTaskContext?.nextTask();
+ if (sessionTasksContext?.nextTask) {
+ return sessionTasksContext?.nextTask();
}
await navigateAfterSelectOrganization(organization);
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx b/packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx
deleted file mode 100644
index 2022e3b69b..0000000000
--- a/packages/clerk-js/src/ui/components/SessionTasks/OrganizationSelectionTask.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { OrganizationListContext } from '../../contexts';
-import { OrganizationList } from '../OrganizationList';
-
-/**
- * @internal
- */
-export function OrganizationSelectionTask() {
- return (
-
-
-
- );
-}
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/index.tsx b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
index 227b4a050c..5dbb574c00 100644
--- a/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
+++ b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
@@ -1,19 +1,58 @@
import { useClerk } from '@clerk/shared/react';
import { eventComponentMounted } from '@clerk/shared/telemetry';
import type { SessionTask } from '@clerk/types';
-import { useCallback, useEffect } from 'react';
+import { useCallback, useContext, useEffect } from 'react';
import { SESSION_TASK_ROUTE_BY_KEY } from '../../../core/sessionTasks';
-import { SessionTaskContext as SessionTaskContext } from '../../contexts/components/SessionTask';
+import { OrganizationListContext, SignInContext, SignUpContext } from '../../../ui/contexts';
+import { Card, LoadingCardContainer, withCardStateProvider } from '../../../ui/elements';
+import { SessionTasksContext as SessionTasksContext } from '../../contexts/components/SessionTasks';
import { Route, Switch, useRouter } from '../../router';
-import { LazyOrganizationSelectionTask } from './lazyTasks';
-import { usePreloadTasks } from './usePreloadTasks';
+import { OrganizationList } from '../OrganizationList';
+
+const SessionTasksStart = withCardStateProvider(() => {
+ const clerk = useClerk();
+ const { navigate } = useRouter();
+
+ useEffect(() => {
+ const timeoutId = setTimeout(() => {
+ void clerk.session?.reload().then(session => {
+ if (!session.currentTask?.key) {
+ void navigate(clerk.buildAfterSignInUrl());
+ return;
+ }
+
+ void navigate(SESSION_TASK_ROUTE_BY_KEY[session.currentTask?.key]);
+ });
+ }, 1000);
+ return () => clearTimeout(timeoutId);
+ }, [navigate, clerk]);
+
+ return (
+
+
+
+
+
+
+ );
+});
function SessionTaskRoutes(): JSX.Element {
return (
-
+
+
+
+
+
+
);
@@ -22,31 +61,34 @@ function SessionTaskRoutes(): JSX.Element {
/**
* @internal
*/
-export function SessionTask({ redirectUrlComplete }: { redirectUrlComplete: string }): JSX.Element {
- usePreloadTasks();
-
- const { __experimental_nextTask, session, telemetry } = useClerk();
+export function SessionTask(): JSX.Element {
+ const clerk = useClerk();
const { navigate } = useRouter();
+ const signInContext = useContext(SignInContext);
+ const signUpContext = useContext(SignUpContext);
- const task = session?.currentTask;
+ const redirectUrlComplete =
+ signInContext?.afterSignInUrl ?? signUpContext?.afterSignUpUrl ?? clerk?.buildAfterSignInUrl();
useEffect(() => {
- if (task) {
- telemetry?.record(eventComponentMounted('SessionTask', { task: task.key }));
+ const task = clerk.session?.currentTask;
+
+ if (!task) {
+ void navigate(redirectUrlComplete);
return;
}
- void navigate(redirectUrlComplete);
- }, [task, telemetry, navigate, redirectUrlComplete]);
+ clerk.telemetry?.record(eventComponentMounted('SessionTask', { task: task.key }));
+ }, [clerk, navigate, redirectUrlComplete]);
const nextTask = useCallback(
- () => __experimental_nextTask({ redirectUrlComplete }),
- [__experimental_nextTask, redirectUrlComplete],
+ () => clerk.__experimental_nextTask({ redirectUrlComplete: redirectUrlComplete }),
+ [clerk, redirectUrlComplete],
);
return (
-
+
-
+
);
}
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/lazyTasks.ts b/packages/clerk-js/src/ui/components/SessionTasks/lazyTasks.ts
deleted file mode 100644
index 990e47b4d9..0000000000
--- a/packages/clerk-js/src/ui/components/SessionTasks/lazyTasks.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { lazy } from 'react';
-
-export const preloadOrganizationSelectionTask = () =>
- import(/* webpackChunkName: "session-tasks"*/ './OrganizationSelectionTask');
-
-const LazyOrganizationSelectionTask = lazy(() =>
- import(/* webpackChunkName: "session-tasks"*/ './OrganizationSelectionTask').then(module => ({
- default: module.OrganizationSelectionTask,
- })),
-);
-
-export { LazyOrganizationSelectionTask };
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts b/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
deleted file mode 100644
index b9c46279e6..0000000000
--- a/packages/clerk-js/src/ui/components/SessionTasks/usePreloadTasks.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { useEnvironment } from '../../../ui/contexts';
-import { useFetch } from '../../../ui/hooks';
-import { preloadOrganizationSelectionTask } from './lazyTasks';
-
-/**
- * Preloads tasks based on the environment settings
- * @internal
- */
-export function usePreloadTasks() {
- const { organizationSettings } = useEnvironment();
-
- if (organizationSettings.forceOrganizationSelection) {
- void useFetch(preloadOrganizationSelectionTask, 'preloadComponent', { staleTime: Infinity });
- }
-}
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
index 0e6b2f5e5f..c2aaa0442b 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
@@ -2,6 +2,7 @@ import { useClerk } from '@clerk/shared/react';
import type { SignInModalProps, SignInProps } from '@clerk/types';
import React from 'react';
+import { SessionTasks } from '../../../ui/lazyModules/components';
import { normalizeRoutingOptions } from '../../../utils/normalizeRoutingOptions';
import { SignInEmailLinkFlowComplete, SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import type { SignUpContextType } from '../../contexts';
@@ -14,7 +15,7 @@ import {
} from '../../contexts';
import { Flow } from '../../customizables';
import { useFetch } from '../../hooks';
-import { SessionTasks } from '../../lazyModules/components';
+import { usePreloadTasks } from '../../hooks/usePreloadTasks';
import { Route, Switch, useRouter, VIRTUAL_ROUTER_BASE_PATH } from '../../router';
import {
LazySignUpContinue,
@@ -130,7 +131,7 @@ function SignInRoutes(): JSX.Element {
-
+
@@ -142,7 +143,7 @@ function SignInRoutes(): JSX.Element {
)}
-
+
@@ -179,6 +180,8 @@ function SignInRoot() {
*/
usePreloadSignUp(signInContext.isCombinedFlow);
+ usePreloadTasks();
+
React.useEffect(() => {
return __internal_setComponentNavigationContext?.({ indexPath, navigate });
}, [indexPath, navigate]);
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
index c928c39a0e..7d2259ddd5 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
@@ -2,10 +2,11 @@ import { useClerk } from '@clerk/shared/react';
import type { SignUpModalProps, SignUpProps } from '@clerk/types';
import React from 'react';
+import { SessionTasks } from '../../../ui/lazyModules/components';
import { SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import { SignUpContext, useSignUpContext, withCoreSessionSwitchGuard } from '../../contexts';
import { Flow } from '../../customizables';
-import { SessionTasks } from '../../lazyModules/components';
+import { usePreloadTasks } from '../../hooks/usePreloadTasks';
import { Route, Switch, useRouter, VIRTUAL_ROUTER_BASE_PATH } from '../../router';
import { SignUpContinue } from './SignUpContinue';
import { SignUpSSOCallback } from './SignUpSSOCallback';
@@ -22,6 +23,8 @@ function RedirectToSignUp() {
}
function SignUpRoutes(): JSX.Element {
+ usePreloadTasks();
+
const { __internal_setComponentNavigationContext } = useClerk();
const { navigate, indexPath } = useRouter();
const signUpContext = useSignUpContext();
@@ -82,7 +85,7 @@ function SignUpRoutes(): JSX.Element {
-
+
diff --git a/packages/clerk-js/src/ui/contexts/components/SessionTask.ts b/packages/clerk-js/src/ui/contexts/components/SessionTask.ts
deleted file mode 100644
index c2b0afa4f2..0000000000
--- a/packages/clerk-js/src/ui/contexts/components/SessionTask.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { createContext } from 'react';
-
-import type { SessionTaskCtx } from '../../types';
-
-export const SessionTaskContext = createContext(null);
diff --git a/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts b/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
new file mode 100644
index 0000000000..02f5d38a51
--- /dev/null
+++ b/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
@@ -0,0 +1,5 @@
+import { createContext } from 'react';
+
+import type { SessionTasksCtx } from '../../types';
+
+export const SessionTasksContext = createContext(null);
diff --git a/packages/clerk-js/src/ui/hooks/usePreloadTasks.ts b/packages/clerk-js/src/ui/hooks/usePreloadTasks.ts
new file mode 100644
index 0000000000..d43a98eded
--- /dev/null
+++ b/packages/clerk-js/src/ui/hooks/usePreloadTasks.ts
@@ -0,0 +1,20 @@
+import { useEnvironment } from '../contexts';
+import { useFetch } from '.';
+
+/**
+ * Preloads tasks based on the environment settings
+ * @internal
+ */
+export function usePreloadTasks() {
+ const { organizationSettings } = useEnvironment();
+
+ const hasTasks = organizationSettings.forceOrganizationSelection;
+
+ void useFetch(
+ hasTasks ? () => import(/* webpackChunkName: "sessionTasks" */ '../components/SessionTasks') : undefined,
+ 'preloadComponent',
+ {
+ staleTime: Infinity,
+ },
+ );
+}
diff --git a/packages/clerk-js/src/ui/lazyModules/components.ts b/packages/clerk-js/src/ui/lazyModules/components.ts
index d48c29e941..4ce33dc78c 100644
--- a/packages/clerk-js/src/ui/lazyModules/components.ts
+++ b/packages/clerk-js/src/ui/lazyModules/components.ts
@@ -95,7 +95,6 @@ export const PricingTable = lazy(() =>
componentImportPaths.PricingTable().then(module => ({ default: module.__experimental_PricingTable })),
);
-export const preloadSessionTasks = () => import(/* webpackChunkName: "sessionTasks" */ '../components/SessionTasks');
export const SessionTasks = lazy(() =>
componentImportPaths.SessionTasks().then(module => ({ default: module.SessionTask })),
);
diff --git a/packages/clerk-js/src/ui/types.ts b/packages/clerk-js/src/ui/types.ts
index 338b9d0ed8..0d7d028ef7 100644
--- a/packages/clerk-js/src/ui/types.ts
+++ b/packages/clerk-js/src/ui/types.ts
@@ -112,8 +112,8 @@ export type __experimental_CheckoutCtx = __experimental_CheckoutProps & {
setIsOpen?: (open: boolean) => void;
};
-export type SessionTaskCtx = {
- nextTask: () => void;
+export type SessionTasksCtx = {
+ nextTask: () => Promise;
};
export type AvailableComponentCtx =
diff --git a/packages/clerk-js/src/utils/componentGuards.ts b/packages/clerk-js/src/utils/componentGuards.ts
index f0084a6a47..4af36e16d5 100644
--- a/packages/clerk-js/src/utils/componentGuards.ts
+++ b/packages/clerk-js/src/utils/componentGuards.ts
@@ -10,6 +10,10 @@ export const sessionExistsAndSingleSessionModeEnabled: ComponentGuard = (clerk,
return !!(clerk.session && environment?.authConfig.singleSessionMode);
};
+export const noSessionExists: ComponentGuard = clerk => {
+ return !clerk.isSignedIn;
+};
+
export const noUserExists: ComponentGuard = clerk => {
return !clerk.user;
};
From 6e7d003dc084fca88c558445e1323a68a3f3fb47 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Sun, 23 Mar 2025 19:53:59 -0300
Subject: [PATCH 5/7] Add changeset
---
.changeset/lazy-impalas-clean.md | 6 +++++
.../OrganizationList/OrganizationListPage.tsx | 2 --
.../src/ui/components/SessionTasks/index.tsx | 24 +++++++++----------
.../ui/contexts/components/SessionTasks.ts | 12 +++++++++-
packages/clerk-js/src/ui/types.ts | 1 +
.../clerk-js/src/utils/componentGuards.ts | 4 ----
packages/types/src/clerk.ts | 2 +-
7 files changed, 30 insertions(+), 21 deletions(-)
create mode 100644 .changeset/lazy-impalas-clean.md
diff --git a/.changeset/lazy-impalas-clean.md b/.changeset/lazy-impalas-clean.md
new file mode 100644
index 0000000000..9aab34ce78
--- /dev/null
+++ b/.changeset/lazy-impalas-clean.md
@@ -0,0 +1,6 @@
+---
+'@clerk/clerk-js': patch
+'@clerk/types': patch
+---
+
+Load tasks based on environment settings
diff --git a/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx b/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx
index 4a5963fc20..d8d2404dbc 100644
--- a/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx
+++ b/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx
@@ -17,8 +17,6 @@ import { organizationListParams } from './utils';
const useOrganizationListInView = () => {
const { userMemberships, userInvitations, userSuggestions } = useOrganizationList(organizationListParams);
- console.log({ userMemberships });
-
const { ref } = useInView({
threshold: 0,
onChange: inView => {
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/index.tsx b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
index 5dbb574c00..dc97a5cb0f 100644
--- a/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
+++ b/packages/clerk-js/src/ui/components/SessionTasks/index.tsx
@@ -6,27 +6,25 @@ import { useCallback, useContext, useEffect } from 'react';
import { SESSION_TASK_ROUTE_BY_KEY } from '../../../core/sessionTasks';
import { OrganizationListContext, SignInContext, SignUpContext } from '../../../ui/contexts';
import { Card, LoadingCardContainer, withCardStateProvider } from '../../../ui/elements';
-import { SessionTasksContext as SessionTasksContext } from '../../contexts/components/SessionTasks';
+import {
+ SessionTasksContext as SessionTasksContext,
+ useSessionTasksContext,
+} from '../../contexts/components/SessionTasks';
import { Route, Switch, useRouter } from '../../router';
import { OrganizationList } from '../OrganizationList';
const SessionTasksStart = withCardStateProvider(() => {
const clerk = useClerk();
const { navigate } = useRouter();
+ const { redirectUrlComplete } = useSessionTasksContext();
useEffect(() => {
+ // Simulates additional latency to avoid a abrupt UI transition when navigating to the next task
const timeoutId = setTimeout(() => {
- void clerk.session?.reload().then(session => {
- if (!session.currentTask?.key) {
- void navigate(clerk.buildAfterSignInUrl());
- return;
- }
-
- void navigate(SESSION_TASK_ROUTE_BY_KEY[session.currentTask?.key]);
- });
- }, 1000);
+ void clerk.__experimental_nextTask({ redirectUrlComplete });
+ }, 500);
return () => clearTimeout(timeoutId);
- }, [navigate, clerk]);
+ }, [navigate, clerk, redirectUrlComplete]);
return (
@@ -82,12 +80,12 @@ export function SessionTask(): JSX.Element {
}, [clerk, navigate, redirectUrlComplete]);
const nextTask = useCallback(
- () => clerk.__experimental_nextTask({ redirectUrlComplete: redirectUrlComplete }),
+ () => clerk.__experimental_nextTask({ redirectUrlComplete }),
[clerk, redirectUrlComplete],
);
return (
-
+
);
diff --git a/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts b/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
index 02f5d38a51..1c9e0be6c5 100644
--- a/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
+++ b/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
@@ -1,5 +1,15 @@
-import { createContext } from 'react';
+import { createContext, useContext } from 'react';
import type { SessionTasksCtx } from '../../types';
export const SessionTasksContext = createContext(null);
+
+export const useSessionTasksContext = () => {
+ const context = useContext(SessionTasksContext);
+
+ if (context === null) {
+ throw new Error('Clerk: useSessionTasksContext called outside of the mounted SessionTasks component.');
+ }
+
+ return context;
+};
diff --git a/packages/clerk-js/src/ui/types.ts b/packages/clerk-js/src/ui/types.ts
index 0d7d028ef7..feac0ee05f 100644
--- a/packages/clerk-js/src/ui/types.ts
+++ b/packages/clerk-js/src/ui/types.ts
@@ -114,6 +114,7 @@ export type __experimental_CheckoutCtx = __experimental_CheckoutProps & {
export type SessionTasksCtx = {
nextTask: () => Promise;
+ redirectUrlComplete?: string;
};
export type AvailableComponentCtx =
diff --git a/packages/clerk-js/src/utils/componentGuards.ts b/packages/clerk-js/src/utils/componentGuards.ts
index 4af36e16d5..f0084a6a47 100644
--- a/packages/clerk-js/src/utils/componentGuards.ts
+++ b/packages/clerk-js/src/utils/componentGuards.ts
@@ -10,10 +10,6 @@ export const sessionExistsAndSingleSessionModeEnabled: ComponentGuard = (clerk,
return !!(clerk.session && environment?.authConfig.singleSessionMode);
};
-export const noSessionExists: ComponentGuard = clerk => {
- return !clerk.isSignedIn;
-};
-
export const noUserExists: ComponentGuard = clerk => {
return !clerk.user;
};
diff --git a/packages/types/src/clerk.ts b/packages/types/src/clerk.ts
index 5ff1e100ad..844fac0794 100644
--- a/packages/types/src/clerk.ts
+++ b/packages/types/src/clerk.ts
@@ -644,7 +644,7 @@ export interface Clerk {
* If all tasks are complete, it navigates to the provided completion URL.
* @experimental
*/
- __experimental_nextTask: (params: NextTaskParams) => Promise;
+ __experimental_nextTask: (params?: NextTaskParams) => Promise;
/**
* This is an optional function.
From 3f7f80b0c87a34e967edf252ff2a986517870697 Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Wed, 26 Mar 2025 12:45:53 -0300
Subject: [PATCH 6/7] Rename `SessionTasks` imports to `LazySessionTasks`
---
packages/clerk-js/src/ui/components/SignIn/SignIn.tsx | 6 +++---
packages/clerk-js/src/ui/components/SignUp/SignUp.tsx | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
index c2aaa0442b..7bb9a3316a 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx
@@ -2,7 +2,7 @@ import { useClerk } from '@clerk/shared/react';
import type { SignInModalProps, SignInProps } from '@clerk/types';
import React from 'react';
-import { SessionTasks } from '../../../ui/lazyModules/components';
+import { SessionTasks as LazySessionTasks } from '../../../ui/lazyModules/components';
import { normalizeRoutingOptions } from '../../../utils/normalizeRoutingOptions';
import { SignInEmailLinkFlowComplete, SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import type { SignUpContextType } from '../../contexts';
@@ -131,7 +131,7 @@ function SignInRoutes(): JSX.Element {
-
+
@@ -143,7 +143,7 @@ function SignInRoutes(): JSX.Element {
)}
-
+
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
index 7d2259ddd5..8668ee07dc 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUp.tsx
@@ -2,7 +2,7 @@ import { useClerk } from '@clerk/shared/react';
import type { SignUpModalProps, SignUpProps } from '@clerk/types';
import React from 'react';
-import { SessionTasks } from '../../../ui/lazyModules/components';
+import { SessionTasks as LazySessionTasks } from '../../../ui/lazyModules/components';
import { SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import { SignUpContext, useSignUpContext, withCoreSessionSwitchGuard } from '../../contexts';
import { Flow } from '../../customizables';
@@ -85,7 +85,7 @@ function SignUpRoutes(): JSX.Element {
-
+
From d772acf0cec25236db24b0793307d8956ed7d3ee Mon Sep 17 00:00:00 2001
From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com>
Date: Wed, 26 Mar 2025 12:49:57 -0300
Subject: [PATCH 7/7] Update bundle max size
---
packages/clerk-js/bundlewatch.config.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json
index 6785631e12..f747ecd60b 100644
--- a/packages/clerk-js/bundlewatch.config.json
+++ b/packages/clerk-js/bundlewatch.config.json
@@ -1,9 +1,9 @@
{
"files": [
- { "path": "./dist/clerk.js", "maxSize": "580.5kB" },
+ { "path": "./dist/clerk.js", "maxSize": "580.7kB" },
{ "path": "./dist/clerk.browser.js", "maxSize": "79.25kB" },
{ "path": "./dist/clerk.headless.js", "maxSize": "55KB" },
- { "path": "./dist/ui-common*.js", "maxSize": "94KB" },
+ { "path": "./dist/ui-common*.js", "maxSize": "96KB" },
{ "path": "./dist/vendors*.js", "maxSize": "30KB" },
{ "path": "./dist/coinbase*.js", "maxSize": "35.5KB" },
{ "path": "./dist/createorganization*.js", "maxSize": "5KB" },