( + Component: ComponentType
,
+ condition: ComponentGuard,
+ redirectUrl: RedirectUrl,
+ warning?: string,
+): (props: P) => null | JSX.Element {
+ const displayName = Component.displayName || Component.name || 'Component';
+ Component.displayName = displayName;
+
+ const HOC = (props: P) => {
+ const { navigate } = useRouter();
+ const clerk = useClerk();
+ const environment = useEnvironment();
+ const options = useOptions();
+
+ const shouldRedirect = condition(clerk, environment, options);
+ React.useEffect(() => {
+ if (shouldRedirect) {
+ if (warning && isDevelopmentFromPublishableKey(clerk.publishableKey)) {
+ console.info(warning);
+ }
+ // TODO: Fix this properly
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
+ navigate(redirectUrl({ clerk, environment, options }));
+ }
+ }, []);
+
+ if (shouldRedirect) {
+ return null;
+ }
+
+ return
(Component: ComponentType
) => { + const displayName = Component.displayName || Component.name || 'Component'; + Component.displayName = displayName; + + const HOC = (props: P) => { + const signInCtx = useSignInContext(); + return withRedirect( + Component, + sessionExistsAndSingleSessionModeEnabled, + ({ clerk }) => signInCtx.afterSignInUrl || clerk.buildAfterSignInUrl(), + warnings.cannotRenderSignInComponentWhenSessionExists, + )(props); + }; + + HOC.displayName = `withRedirectToAfterSignIn(${displayName})`; + + return HOC; +}; + +export const withRedirectToAfterSignUp =
(Component: ComponentType
) => { + const displayName = Component.displayName || Component.name || 'Component'; + Component.displayName = displayName; + + const HOC = (props: P) => { + const signUpCtx = useSignUpContext(); + return withRedirect( + Component, + sessionExistsAndSingleSessionModeEnabled, + ({ clerk }) => signUpCtx.afterSignUpUrl || clerk.buildAfterSignUpUrl(), + warnings.cannotRenderSignUpComponentWhenSessionExists, + )(props); + }; + + HOC.displayName = `withRedirectToAfterSignUp(${displayName})`; + + return HOC; +}; + +export const withRedirectToHomeSingleSessionGuard =
(Component: ComponentType
) => + withRedirect( + Component, + sessionExistsAndSingleSessionModeEnabled, + ({ environment }) => environment.displayConfig.homeUrl, + warnings.cannotRenderComponentWhenSessionExists, + ); diff --git a/packages/clerk-js/src/ui/common/withRedirectToHome.tsx b/packages/clerk-js/src/ui/common/withRedirectToHome.tsx deleted file mode 100644 index 9309dfe231d..00000000000 --- a/packages/clerk-js/src/ui/common/withRedirectToHome.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { useClerk } from '@clerk/shared/react'; -import type { ComponentType } from 'react'; -import React from 'react'; - -import { warnings } from '../../core/warnings'; -import type { ComponentGuard } from '../../utils'; -import { noOrganizationExists, noUserExists, sessionExistsAndSingleSessionModeEnabled } from '../../utils'; -import { useEnvironment, useOptions } from '../contexts'; -import { useRouter } from '../router'; -import type { AvailableComponentProps } from '../types'; - -function withRedirectToHome
( - Component: ComponentType
,
- condition: ComponentGuard,
- warning?: string,
-): (props: P) => null | JSX.Element {
- const displayName = Component.displayName || Component.name || 'Component';
- Component.displayName = displayName;
-
- const HOC = (props: P) => {
- const { navigate } = useRouter();
- const clerk = useClerk();
- const environment = useEnvironment();
- const options = useOptions();
-
- const shouldRedirect = condition(clerk, environment, options);
- React.useEffect(() => {
- if (shouldRedirect) {
- if (warning && environment.displayConfig.instanceEnvironmentType === 'development') {
- console.info(warning);
- }
- // TODO: Fix this properly
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
- navigate(environment.displayConfig.homeUrl);
- }
- }, []);
-
- if (shouldRedirect) {
- return null;
- }
-
- return
(Component: ComponentType
) => - withRedirectToHome( - Component, - sessionExistsAndSingleSessionModeEnabled, - warnings.cannotRenderComponentWhenSessionExists, - ); - -export const withRedirectToHomeUserGuard =
(Component: ComponentType
) => - withRedirectToHome(Component, noUserExists, warnings.cannotRenderComponentWhenUserDoesNotExist); - -export const withRedirectToHomeOrganizationGuard =
(Component: ComponentType
) =>
- withRedirectToHome(Component, noOrganizationExists, warnings.cannotRenderComponentWhenOrgDoesNotExist);
diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfile.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfile.tsx
index 8560fd9c38e..439ada76a6e 100644
--- a/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfile.tsx
+++ b/packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationProfile.tsx
@@ -2,7 +2,7 @@ import { useOrganization } from '@clerk/shared/react';
import type { OrganizationProfileModalProps, OrganizationProfileProps } from '@clerk/types';
import React from 'react';
-import { withOrganizationsEnabledGuard, withRedirectToHomeOrganizationGuard } from '../../common';
+import { withOrganizationsEnabledGuard } from '../../common';
import { ComponentContext, withCoreUserGuard } from '../../contexts';
import { Flow } from '../../customizables';
import { ProfileCard, withCardStateProvider } from '../../elements';
@@ -44,10 +44,12 @@ const AuthenticatedRoutes = withCoreUserGuard(() => {
);
});
-export const OrganizationProfile = withRedirectToHomeOrganizationGuard(
- withOrganizationsEnabledGuard(withCardStateProvider(_OrganizationProfile), 'OrganizationProfile', {
+export const OrganizationProfile = withOrganizationsEnabledGuard(
+ withCardStateProvider(_OrganizationProfile),
+ 'OrganizationProfile',
+ {
mode: 'redirect',
- }),
+ },
);
export const OrganizationProfileModal = (props: OrganizationProfileModalProps): JSX.Element => {
diff --git a/packages/clerk-js/src/ui/components/SignIn/ResetPassword.tsx b/packages/clerk-js/src/ui/components/SignIn/ResetPassword.tsx
index f189a36b7f5..2b7af25d843 100644
--- a/packages/clerk-js/src/ui/components/SignIn/ResetPassword.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/ResetPassword.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import { clerkInvalidFAPIResponse } from '../../../core/errors';
-import { withRedirectToHomeSingleSessionGuard } from '../../common';
import { useCoreSignIn, useEnvironment } from '../../contexts';
import { Col, descriptors, localizationKeys, useLocalizations } from '../../customizables';
import { Card, CardAlert, Form, Header, useCardState, withCardStateProvider } from '../../elements';
@@ -148,4 +147,4 @@ export const _ResetPassword = () => {
);
};
-export const ResetPassword = withRedirectToHomeSingleSessionGuard(withCardStateProvider(_ResetPassword));
+export const ResetPassword = withCardStateProvider(_ResetPassword);
diff --git a/packages/clerk-js/src/ui/components/SignIn/ResetPasswordSuccess.tsx b/packages/clerk-js/src/ui/components/SignIn/ResetPasswordSuccess.tsx
index 97298a62720..5032954f3c3 100644
--- a/packages/clerk-js/src/ui/components/SignIn/ResetPasswordSuccess.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/ResetPasswordSuccess.tsx
@@ -1,4 +1,3 @@
-import { withRedirectToHomeSingleSessionGuard } from '../../common';
import { Col, descriptors, localizationKeys, Spinner, Text } from '../../customizables';
import { Card, CardAlert, Header, useCardState, withCardStateProvider } from '../../elements';
import { useSetSessionWithTimeout } from '../../hooks/useSetSessionWithTimeout';
@@ -33,4 +32,4 @@ export const _ResetPasswordSuccess = () => {
);
};
-export const ResetPasswordSuccess = withRedirectToHomeSingleSessionGuard(withCardStateProvider(_ResetPasswordSuccess));
+export const ResetPasswordSuccess = withCardStateProvider(_ResetPasswordSuccess);
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInAccountSwitcher.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInAccountSwitcher.tsx
index 6f716e37087..5d1ccc4fb3e 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignInAccountSwitcher.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignInAccountSwitcher.tsx
@@ -1,4 +1,4 @@
-import { withRedirectToHomeSingleSessionGuard } from '../../common';
+import { withRedirectToAfterSignIn } from '../../common';
import { useEnvironment, useSignInContext } from '../../contexts';
import { Col, descriptors, Flow, Icon } from '../../customizables';
import { Card, CardAlert, Header, PreviewButton, UserPreview, withCardStateProvider } from '../../elements';
@@ -77,6 +77,4 @@ const _SignInAccountSwitcher = () => {
);
};
-export const SignInAccountSwitcher = withRedirectToHomeSingleSessionGuard(
- withCardStateProvider(_SignInAccountSwitcher),
-);
+export const SignInAccountSwitcher = withRedirectToAfterSignIn(withCardStateProvider(_SignInAccountSwitcher));
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOne.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOne.tsx
index 804fe73186c..2169bbd101b 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignInFactorOne.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignInFactorOne.tsx
@@ -1,7 +1,7 @@
import type { ResetPasswordCodeFactor, SignInFactor } from '@clerk/types';
import React from 'react';
-import { withRedirectToHomeSingleSessionGuard } from '../../common';
+import { withRedirectToAfterSignIn } from '../../common';
import { useCoreSignIn, useEnvironment } from '../../contexts';
import { ErrorCard, LoadingCard, withCardStateProvider } from '../../elements';
import { useAlternativeStrategies } from '../../hooks/useAlternativeStrategies';
@@ -197,4 +197,4 @@ export function _SignInFactorOne(): JSX.Element {
}
}
-export const SignInFactorOne = withRedirectToHomeSingleSessionGuard(withCardStateProvider(_SignInFactorOne));
+export const SignInFactorOne = withRedirectToAfterSignIn(withCardStateProvider(_SignInFactorOne));
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInFactorTwo.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInFactorTwo.tsx
index 59294503010..460589cf1e9 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignInFactorTwo.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignInFactorTwo.tsx
@@ -1,7 +1,7 @@
import type { SignInFactor } from '@clerk/types';
import React from 'react';
-import { withRedirectToHomeSingleSessionGuard } from '../../common';
+import { withRedirectToAfterSignIn } from '../../common';
import { useCoreSignIn } from '../../contexts';
import { LoadingCard, withCardStateProvider } from '../../elements';
import { SignInFactorTwoAlternativeMethods } from './SignInFactorTwoAlternativeMethods';
@@ -81,4 +81,4 @@ export function _SignInFactorTwo(): JSX.Element {
}
}
-export const SignInFactorTwo = withRedirectToHomeSingleSessionGuard(withCardStateProvider(_SignInFactorTwo));
+export const SignInFactorTwo = withRedirectToAfterSignIn(withCardStateProvider(_SignInFactorTwo));
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInSSOCallback.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInSSOCallback.tsx
index c1bad1c3664..07bfaed52d2 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignInSSOCallback.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignInSSOCallback.tsx
@@ -1,3 +1,3 @@
-import { SSOCallback, withRedirectToHomeSingleSessionGuard } from '../../common';
+import { SSOCallback, withRedirectToAfterSignIn } from '../../common';
-export const SignInSSOCallback = withRedirectToHomeSingleSessionGuard(SSOCallback);
+export const SignInSSOCallback = withRedirectToAfterSignIn(SSOCallback);
diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx
index 18271f82330..0d9f9f4a915 100644
--- a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx
+++ b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx
@@ -6,11 +6,7 @@ import { ERROR_CODES } from '../../../core/constants';
import { clerkInvalidFAPIResponse } from '../../../core/errors';
import { getClerkQueryParam } from '../../../utils';
import type { SignInStartIdentifier } from '../../common';
-import {
- getIdentifierControlDisplayValues,
- groupIdentifiers,
- withRedirectToHomeSingleSessionGuard,
-} from '../../common';
+import { getIdentifierControlDisplayValues, groupIdentifiers, withRedirectToAfterSignIn } from '../../common';
import { buildSSOCallbackURL } from '../../common/redirects';
import { useCoreSignIn, useEnvironment, useSignInContext } from '../../contexts';
import { Col, descriptors, Flow, localizationKeys } from '../../customizables';
@@ -390,4 +386,4 @@ const InstantPasswordRow = ({ field }: { field?: FormControlState<'password'> })
);
};
-export const SignInStart = withRedirectToHomeSingleSessionGuard(withCardStateProvider(_SignInStart));
+export const SignInStart = withRedirectToAfterSignIn(withCardStateProvider(_SignInStart));
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpSSOCallback.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpSSOCallback.tsx
index a17cff10c54..a72a27627fa 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUpSSOCallback.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUpSSOCallback.tsx
@@ -1,3 +1,3 @@
-import { SSOCallback, withRedirectToHomeSingleSessionGuard } from '../../common';
+import { SSOCallback, withRedirectToAfterSignUp } from '../../common';
-export const SignUpSSOCallback = withRedirectToHomeSingleSessionGuard(SSOCallback);
+export const SignUpSSOCallback = withRedirectToAfterSignUp(SSOCallback);
diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
index 79fafd6967c..a1e1b4e6d0d 100644
--- a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
+++ b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx
@@ -3,7 +3,7 @@ import React from 'react';
import { ERROR_CODES } from '../../../core/constants';
import { getClerkQueryParam } from '../../../utils/getClerkQueryParam';
-import { buildSSOCallbackURL, withRedirectToHomeSingleSessionGuard } from '../../common';
+import { buildSSOCallbackURL, withRedirectToAfterSignUp } from '../../common';
import { useCoreSignUp, useEnvironment, useSignUpContext } from '../../contexts';
import { descriptors, Flex, Flow, localizationKeys, useAppearance, useLocalizations } from '../../customizables';
import {
@@ -289,4 +289,4 @@ function _SignUpStart(): JSX.Element {
);
}
-export const SignUpStart = withRedirectToHomeSingleSessionGuard(withCardStateProvider(_SignUpStart));
+export const SignUpStart = withRedirectToAfterSignUp(withCardStateProvider(_SignUpStart));
diff --git a/packages/clerk-js/src/ui/components/UserProfile/UserProfile.tsx b/packages/clerk-js/src/ui/components/UserProfile/UserProfile.tsx
index 8a586db1fbf..9cbf9c1eebf 100644
--- a/packages/clerk-js/src/ui/components/UserProfile/UserProfile.tsx
+++ b/packages/clerk-js/src/ui/components/UserProfile/UserProfile.tsx
@@ -1,7 +1,6 @@
import type { UserProfileModalProps, UserProfileProps } from '@clerk/types';
import React from 'react';
-import { withRedirectToHomeUserGuard } from '../../common';
import { ComponentContext, withCoreUserGuard } from '../../contexts';
import { Flow } from '../../customizables';
import { ProfileCard, withCardStateProvider } from '../../elements';
@@ -51,7 +50,7 @@ const AuthenticatedRoutes = withCoreUserGuard(() => {
);
});
-export const UserProfile = withRedirectToHomeUserGuard(withCardStateProvider(_UserProfile));
+export const UserProfile = withCardStateProvider(_UserProfile);
export const UserProfileModal = (props: UserProfileModalProps): JSX.Element => {
const userProfileProps: UserProfileCtx = {
diff --git a/packages/react/src/isomorphicClerk.ts b/packages/react/src/isomorphicClerk.ts
index fa3e04a6b47..98c2a29cb5c 100644
--- a/packages/react/src/isomorphicClerk.ts
+++ b/packages/react/src/isomorphicClerk.ts
@@ -73,7 +73,8 @@ type IsomorphicLoadedClerk = Without<
| 'buildUserProfileUrl'
| 'buildCreateOrganizationUrl'
| 'buildOrganizationProfileUrl'
- | 'buildHomeUrl'
+ | 'buildAfterSignUpUrl'
+ | 'buildAfterSignInUrl'
| 'buildUrlWithAuth'
| 'handleRedirectCallback'
| 'handleUnauthenticated'
@@ -111,10 +112,11 @@ type IsomorphicLoadedClerk = Without<
// TODO: Align return type
buildOrganizationProfileUrl: () => string | void;
// TODO: Align return type
- buildHomeUrl: () => string | void;
- // TODO: Align return type
buildUrlWithAuth: (to: string, opts?: BuildUrlWithAuthParams | undefined) => string | void;
-
+ // TODO: Align return type
+ buildAfterSignInUrl: () => string | void;
+ // TODO: Align return type
+ buildAfterSignUpUrl: () => string | void;
// TODO: Align optional props
mountUserButton: (node: HTMLDivElement, props: UserButtonProps) => void;
mountOrganizationList: (node: HTMLDivElement, props: OrganizationListProps) => void;
@@ -260,6 +262,24 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}
};
+ buildAfterSignInUrl = (): string | void => {
+ const callback = () => this.clerkjs?.buildAfterSignInUrl() || '';
+ if (this.clerkjs && this.#loaded) {
+ return callback();
+ } else {
+ this.premountMethodCalls.set('buildAfterSignInUrl', callback);
+ }
+ };
+
+ buildAfterSignUpUrl = (): string | void => {
+ const callback = () => this.clerkjs?.buildAfterSignUpUrl() || '';
+ if (this.clerkjs && this.#loaded) {
+ return callback();
+ } else {
+ this.premountMethodCalls.set('buildAfterSignUpUrl', callback);
+ }
+ };
+
buildUserProfileUrl = (): string | void => {
const callback = () => this.clerkjs?.buildUserProfileUrl() || '';
if (this.clerkjs && this.#loaded) {
@@ -287,15 +307,6 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}
};
- buildHomeUrl = (): string | void => {
- const callback = () => this.clerkjs?.buildHomeUrl() || '';
- if (this.clerkjs && this.#loaded) {
- return callback();
- } else {
- this.premountMethodCalls.set('buildHomeUrl', callback);
- }
- };
-
buildUrlWithAuth = (to: string, opts?: BuildUrlWithAuthParams | undefined): string | void => {
const callback = () => this.clerkjs?.buildUrlWithAuth(to, opts) || '';
if (this.clerkjs && this.#loaded) {
@@ -808,13 +819,21 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}
};
- redirectToHome = async (): Promise