Skip to content

Commit de90d9b

Browse files
authored
fix(remix): Automatically infer path to where component is mounted (clerk#3104)
* fix(remix): Automatically infer path to where component is mounted * chore(repo): Add Changeset * fix(clerk-js): Add usePathnameWithoutSplatRouteParams to handle splat routes
1 parent 97da7c3 commit de90d9b

3 files changed

Lines changed: 34 additions & 8 deletions

File tree

.changeset/wicked-worms-draw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/remix': patch
3+
---
4+
5+
Automatically infer the path for where the component is mounted.

packages/remix/src/client/uiComponents.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,23 @@ import type {
1515
} from '@clerk/types';
1616
import React from 'react';
1717

18-
import { useClerkRemixOptions } from './RemixOptionsContext';
18+
import { usePathnameWithoutSplatRouteParams } from './usePathnameWithoutSplatRouteParams';
1919

2020
// The assignment of UserProfile with BaseUserProfile props is used
2121
// to support the CustomPage functionality (eg UserProfile.Page)
2222
// Also the `typeof BaseUserProfile` is used to resolved the following error:
2323
// "The inferred type of 'UserProfile' cannot be named without a reference to ..."
2424
export const UserProfile: typeof BaseUserProfile = Object.assign(
2525
(props: UserProfileProps) => {
26-
return <BaseUserProfile {...useRoutingProps('UserProfile', props)} />;
26+
const path = usePathnameWithoutSplatRouteParams();
27+
return <BaseUserProfile {...useRoutingProps('UserProfile', props, { path })} />;
2728
},
2829
{ ...BaseUserProfile },
2930
);
3031

3132
export const CreateOrganization = (props: CreateOrganizationProps) => {
32-
return <BaseCreateOrganization {...useRoutingProps('CreateOrganization', props)} />;
33+
const path = usePathnameWithoutSplatRouteParams();
34+
return <BaseCreateOrganization {...useRoutingProps('CreateOrganization', props, { path })} />;
3335
};
3436

3537
// The assignment of OrganizationProfile with BaseOrganizationProfile props is used
@@ -38,17 +40,18 @@ export const CreateOrganization = (props: CreateOrganizationProps) => {
3840
// "The inferred type of 'OrganizationProfile' cannot be named without a reference to ..."
3941
export const OrganizationProfile: typeof BaseOrganizationProfile = Object.assign(
4042
(props: OrganizationProfileProps) => {
41-
return <BaseOrganizationProfile {...useRoutingProps('OrganizationProfile', props)} />;
43+
const path = usePathnameWithoutSplatRouteParams();
44+
return <BaseOrganizationProfile {...useRoutingProps('OrganizationProfile', props, { path })} />;
4245
},
4346
{ ...BaseOrganizationProfile },
4447
);
4548

4649
export const SignIn = (props: SignInProps) => {
47-
const { signInUrl } = useClerkRemixOptions();
48-
return <BaseSignIn {...useRoutingProps('SignIn', props, { path: signInUrl })} />;
50+
const path = usePathnameWithoutSplatRouteParams();
51+
return <BaseSignIn {...useRoutingProps('SignIn', props, { path })} />;
4952
};
5053

5154
export const SignUp = (props: SignUpProps) => {
52-
const { signUpUrl } = useClerkRemixOptions();
53-
return <BaseSignUp {...useRoutingProps('SignUp', props, { path: signUpUrl })} />;
55+
const path = usePathnameWithoutSplatRouteParams();
56+
return <BaseSignUp {...useRoutingProps('SignUp', props, { path })} />;
5457
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useLocation, useParams } from '@remix-run/react';
2+
3+
export const usePathnameWithoutSplatRouteParams = () => {
4+
const params = useParams();
5+
const { pathname } = useLocation();
6+
7+
// Get the splat route params
8+
// Remix store splat route params in an object with a key of '*'
9+
// If there are no splat route params, we fallback to an empty string
10+
const splatRouteParam = params['*'] || '';
11+
12+
// Remove the splat route param from the pathname
13+
// so we end up with the pathname where the components are mounted at
14+
// eg /user/123/profile/security will return /user/123/profile as the path
15+
const path = pathname.replace(splatRouteParam, '').replace(/\/$/, '').replace(/^\//, '').trim();
16+
17+
return `/${path}`;
18+
};

0 commit comments

Comments
 (0)