Skip to content

Commit ab4eb56

Browse files
authored
feat(clerk-js,types): Drop redirectToHome in favour of redirectToAfterSignIn & redirectToAfterSignUp [SDK-875] (#2251)
* feat(clerk-js,types): Dropped redirectToHome and added redirectToAfterSignIn & redirectToAfterSignUp * feat(clerk-js,types): Add defaults for buildRedirectToAfterSignUpUrl & buildRedirectToAfterSignInUrl * feat(clerk-js,types): Added withRedirectToAfterSignIn & withRedirectToAfterSignUp * fix(types): Update types for retheme * chore(repo): Update Changesets * refactor(clerk-js): Remove withRedirectToHomeUserGuard from UserProfile * refactor(clerk-js): Remove withRedirectToHomeOrganizationGuard from OrganizationProfile * fix(clerk-js): Drop withRedirect from ui.retheme * fix(clerk-js): Show warnings when User is not signed in or Organization is not active * test(clerk-js): Update tests for withRedirect * fix(clerk-js,shared): Added isDevelopmentFromPublishableKey & isProductionFromPublishableKey * fix(clerk-react): Add buildAfterSignInUrl & buildAfterSignUpUrl * test(clerk-js): Fix withRedirect tests * test(clerk-js): Fix withRedirect tests * test(clerk-js): Remove unneeded React import
1 parent 385cc77 commit ab4eb56

24 files changed

+324
-239
lines changed

.changeset/pretty-scissors-thank.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@clerk/clerk-js': major
3+
'@clerk/clerk-react': major
4+
'@clerk/types': patch
5+
---
6+
7+
Drop `redirectToHome` redirect method in favour of `redirectToAfterSignUp` or `redirectToAfterSignIn`.
8+
9+
When the `<SignIn/>` and `<SignUp/>` components are rendered while a user is already logged in, they will now redirect to the configured `afterSignIn` and `afterSignUp` URLs, respectively. Previously, the redirect URL was set to the home URL configured in the dashboard.

packages/clerk-js/src/core/clerk.redirects.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ describe('Clerk singleton - Redirects', () => {
9595
mockNavigate = jest.fn((to: string) => Promise.resolve(to));
9696
});
9797

98-
describe('.redirectTo(SignUp|SignIn|UserProfile|Home|CreateOrganization|OrganizationProfile)', () => {
98+
describe('.redirectTo(SignUp|SignIn|UserProfile|AfterSignIn|AfterSignUp|CreateOrganization|OrganizationProfile)', () => {
9999
let clerkForProductionInstance: Clerk;
100100
let clerkForDevelopmentInstance: Clerk;
101101

@@ -152,12 +152,20 @@ describe('Clerk singleton - Redirects', () => {
152152
expect(mockNavigate).toHaveBeenNthCalledWith(2, '/user-profile');
153153
});
154154

155-
it('redirects to home', async () => {
156-
await clerkForProductionInstance.redirectToHome();
157-
expect(mockNavigate).toHaveBeenNthCalledWith(1, '/home');
155+
it('redirects to afterSignUp', async () => {
156+
await clerkForProductionInstance.redirectToAfterSignUp();
157+
expect(mockNavigate).toHaveBeenNthCalledWith(1, '/');
158158

159-
await clerkForDevelopmentInstance.redirectToHome();
160-
expect(mockNavigate).toHaveBeenNthCalledWith(2, '/home');
159+
await clerkForDevelopmentInstance.redirectToAfterSignUp();
160+
expect(mockNavigate).toHaveBeenNthCalledWith(2, '/');
161+
});
162+
163+
it('redirects to afterSignIn', async () => {
164+
await clerkForProductionInstance.redirectToAfterSignIn();
165+
expect(mockNavigate).toHaveBeenNthCalledWith(1, '/');
166+
167+
await clerkForDevelopmentInstance.redirectToAfterSignIn();
168+
expect(mockNavigate).toHaveBeenNthCalledWith(2, '/');
161169
});
162170

163171
it('redirects to create organization', async () => {
@@ -242,14 +250,6 @@ describe('Clerk singleton - Redirects', () => {
242250
expect(mockHref).toHaveBeenNthCalledWith(2, 'http://another-test.host/user-profile#__clerk_db_jwt[deadbeef]');
243251
});
244252

245-
it('redirects to home', async () => {
246-
await clerkForProductionInstance.redirectToHome();
247-
expect(mockHref).toHaveBeenNthCalledWith(1, 'http://another-test.host/home');
248-
249-
await clerkForDevelopmentInstance.redirectToHome();
250-
expect(mockHref).toHaveBeenNthCalledWith(2, 'http://another-test.host/home#__clerk_db_jwt[deadbeef]');
251-
});
252-
253253
it('redirects to create organization', async () => {
254254
await clerkForProductionInstance.redirectToCreateOrganization();
255255
expect(mockHref).toHaveBeenNthCalledWith(1, 'http://another-test.host/create-organization');

packages/clerk-js/src/core/clerk.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ export class Clerk implements ClerkInterface {
327327
public openSignIn = (props?: SignInProps): void => {
328328
this.assertComponentsReady(this.#componentControls);
329329
if (sessionExistsAndSingleSessionModeEnabled(this, this.#environment) && this.#instanceType === 'development') {
330-
return console.info(warnings.cannotOpenSignUpOrSignUp);
330+
console.info(warnings.cannotOpenSignUpOrSignUp);
331+
return;
331332
}
332333
void this.#componentControls
333334
.ensureMounted({ preloadHint: 'SignIn' })
@@ -372,7 +373,8 @@ export class Clerk implements ClerkInterface {
372373
public openOrganizationProfile = (props?: OrganizationProfileProps): void => {
373374
this.assertComponentsReady(this.#componentControls);
374375
if (noOrganizationExists(this) && this.#instanceType === 'development') {
375-
return console.info(warnings.cannotOpenOrgProfile);
376+
console.info(warnings.cannotOpenOrgProfile);
377+
return;
376378
}
377379
void this.#componentControls
378380
.ensureMounted({ preloadHint: 'OrganizationProfile' })
@@ -442,6 +444,10 @@ export class Clerk implements ClerkInterface {
442444

443445
public mountUserProfile = (node: HTMLDivElement, props?: UserProfileProps): void => {
444446
this.assertComponentsReady(this.#componentControls);
447+
if (noUserExists(this) && this.#instanceType === 'development') {
448+
console.info(warnings.cannotRenderComponentWhenUserDoesNotExist);
449+
return;
450+
}
445451
void this.#componentControls.ensureMounted({ preloadHint: 'UserProfile' }).then(controls =>
446452
controls.mountComponent({
447453
name: 'UserProfile',
@@ -465,6 +471,10 @@ export class Clerk implements ClerkInterface {
465471

466472
public mountOrganizationProfile = (node: HTMLDivElement, props?: OrganizationProfileProps) => {
467473
this.assertComponentsReady(this.#componentControls);
474+
if (noOrganizationExists(this) && this.#instanceType === 'development') {
475+
console.info(warnings.cannotRenderComponentWhenOrgDoesNotExist);
476+
return;
477+
}
468478
void this.#componentControls.ensureMounted({ preloadHint: 'OrganizationProfile' }).then(controls =>
469479
controls.mountComponent({
470480
name: 'OrganizationProfile',
@@ -736,6 +746,22 @@ export class Clerk implements ClerkInterface {
736746
return this.buildUrlWithAuth(this.#environment.displayConfig.homeUrl);
737747
}
738748

749+
public buildAfterSignInUrl(): string {
750+
if (!this.#options.afterSignInUrl) {
751+
return '/';
752+
}
753+
754+
return this.buildUrlWithAuth(this.#options.afterSignInUrl);
755+
}
756+
757+
public buildAfterSignUpUrl(): string {
758+
if (!this.#options.afterSignUpUrl) {
759+
return '/';
760+
}
761+
762+
return this.buildUrlWithAuth(this.#options.afterSignUpUrl);
763+
}
764+
739765
public buildCreateOrganizationUrl(): string {
740766
if (!this.#environment || !this.#environment.displayConfig) {
741767
return '';
@@ -812,9 +838,16 @@ export class Clerk implements ClerkInterface {
812838
return;
813839
};
814840

815-
public redirectToHome = async (): Promise<unknown> => {
841+
public redirectToAfterSignIn = async (): Promise<unknown> => {
842+
if (inBrowser()) {
843+
return this.navigate(this.buildAfterSignInUrl());
844+
}
845+
return;
846+
};
847+
848+
public redirectToAfterSignUp = async (): Promise<unknown> => {
816849
if (inBrowser()) {
817-
return this.navigate(this.buildHomeUrl());
850+
return this.navigate(this.buildAfterSignUpUrl());
818851
}
819852
return;
820853
};

packages/clerk-js/src/core/warnings.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ const formatWarning = (msg: string) => {
55
const warnings = {
66
cannotRenderComponentWhenSessionExists:
77
'The <SignUp/> and <SignIn/> components cannot render when a user is already signed in, unless the application allows multiple sessions. Since a user is signed in and this application only allows a single session, Clerk is redirecting to the Home URL instead.',
8+
cannotRenderSignUpComponentWhenSessionExists:
9+
'The <SignUp/> component cannot render when a user is already signed in, unless the application allows multiple sessions. Since a user is signed in and this application only allows a single session, Clerk is redirecting to the value setted in `afterSignUp` URL instead.',
10+
cannotRenderSignInComponentWhenSessionExists:
11+
'The <SignIn/> component cannot render when a user is already signed in, unless the application allows multiple sessions. Since a user is signed in and this application only allows a single session, Clerk is redirecting to the `afterSignIn` URL instead.',
812
cannotRenderComponentWhenUserDoesNotExist:
9-
'<UserProfile/> cannot render unless a user is signed in. Since no user is signed in, Clerk is redirecting to the Home URL instead. (This notice only appears in development.)',
10-
cannotRenderComponentWhenOrgDoesNotExist: `<OrganizationProfile/> cannot render unless an organization is active. Since no organization is currently active, Clerk is redirecting to the Home URL instead.`,
13+
'<UserProfile/> cannot render unless a user is signed in. Since no user is signed in, this is no-op.',
14+
cannotRenderComponentWhenOrgDoesNotExist: `<OrganizationProfile/> cannot render unless an organization is active. Since no organization is currently active, this is no-op.`,
1115
cannotOpenOrgProfile:
1216
'The OrganizationProfile cannot render unless an organization is active. Since no organization is currently active, this is no-op.',
1317
cannotOpenUserProfile:
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
3+
import { render } from '../../../testUtils';
4+
import { bindCreateFixtures } from '../../utils/test/createFixtures';
5+
import { withRedirect } from '../withRedirect';
6+
7+
const { createFixtures } = bindCreateFixtures('SignIn');
8+
9+
describe('withRedirect', () => {
10+
it('redirects to the redirect url provided when condition is met', async () => {
11+
const { wrapper, fixtures } = await createFixtures(f => {
12+
f.withUser({});
13+
});
14+
15+
const WithHOC = withRedirect(
16+
() => <></>,
17+
() => true,
18+
() => '/',
19+
'Redirecting to /',
20+
);
21+
22+
render(<WithHOC />, { wrapper });
23+
24+
expect(fixtures.router.navigate).toHaveBeenCalledWith('/');
25+
});
26+
27+
it('does no redirects to the redirect url provided when the condition is not met', async () => {
28+
const { wrapper, fixtures } = await createFixtures(f => {
29+
f.withUser({});
30+
});
31+
32+
const WithHOC = withRedirect(
33+
() => <></>,
34+
() => false,
35+
() => '/',
36+
'Redirecting to /',
37+
);
38+
39+
render(<WithHOC />, { wrapper });
40+
41+
expect(fixtures.router.navigate).not.toHaveBeenCalledWith('/');
42+
});
43+
});

packages/clerk-js/src/ui/common/__tests__/withRedirectToHome.test.tsx

Lines changed: 0 additions & 102 deletions
This file was deleted.

packages/clerk-js/src/ui/common/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export * from './Gate';
66
export * from './InfiniteListSpinner';
77
export * from './redirects';
88
export * from './verification';
9-
export * from './withRedirectToHome';
9+
export * from './withRedirect';
1010
export * from './SSOCallback';
1111
export * from './EmailLinkVerify';
1212
export * from './EmailLinkStatusCard';

0 commit comments

Comments
 (0)