From ebae761c01bfa5c79534c1ef78033f14172cea29 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Wed, 3 Apr 2024 17:50:07 +0300 Subject: [PATCH 1/3] fix(remix): Automatically infer path to where component is mounted --- packages/remix/src/client/uiComponents.tsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/remix/src/client/uiComponents.tsx b/packages/remix/src/client/uiComponents.tsx index d3cd7f457c0..3c28d5e28fb 100644 --- a/packages/remix/src/client/uiComponents.tsx +++ b/packages/remix/src/client/uiComponents.tsx @@ -13,23 +13,24 @@ import type { SignUpProps, UserProfileProps, } from '@clerk/types'; +import { useLocation } from '@remix-run/react'; import React from 'react'; -import { useClerkRemixOptions } from './RemixOptionsContext'; - // The assignment of UserProfile with BaseUserProfile props is used // to support the CustomPage functionality (eg UserProfile.Page) // Also the `typeof BaseUserProfile` is used to resolved the following error: // "The inferred type of 'UserProfile' cannot be named without a reference to ..." export const UserProfile: typeof BaseUserProfile = Object.assign( (props: UserProfileProps) => { - return ; + const { pathname: path } = useLocation(); + return ; }, { ...BaseUserProfile }, ); export const CreateOrganization = (props: CreateOrganizationProps) => { - return ; + const { pathname: path } = useLocation(); + return ; }; // The assignment of OrganizationProfile with BaseOrganizationProfile props is used @@ -38,17 +39,18 @@ export const CreateOrganization = (props: CreateOrganizationProps) => { // "The inferred type of 'OrganizationProfile' cannot be named without a reference to ..." export const OrganizationProfile: typeof BaseOrganizationProfile = Object.assign( (props: OrganizationProfileProps) => { - return ; + const { pathname: path } = useLocation(); + return ; }, { ...BaseOrganizationProfile }, ); export const SignIn = (props: SignInProps) => { - const { signInUrl } = useClerkRemixOptions(); - return ; + const { pathname: path } = useLocation(); + return ; }; export const SignUp = (props: SignUpProps) => { - const { signUpUrl } = useClerkRemixOptions(); - return ; + const { pathname: path } = useLocation(); + return ; }; From c8c60acce7fdc8a4dba82a79884009b39fc087d7 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Wed, 3 Apr 2024 18:14:29 +0300 Subject: [PATCH 2/3] chore(repo): Add Changeset --- .changeset/wicked-worms-draw.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wicked-worms-draw.md diff --git a/.changeset/wicked-worms-draw.md b/.changeset/wicked-worms-draw.md new file mode 100644 index 00000000000..3af49c5eb69 --- /dev/null +++ b/.changeset/wicked-worms-draw.md @@ -0,0 +1,5 @@ +--- +'@clerk/remix': patch +--- + +Automatically infer the path for where the component is mounted. From d87a2f074e8b09ce7cf055e8cad265e9dad77166 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Fri, 5 Apr 2024 00:13:03 +0300 Subject: [PATCH 3/3] fix(clerk-js): Add usePathnameWithoutSplatRouteParams to handle splat routes --- packages/remix/src/client/uiComponents.tsx | 13 +++++++------ .../usePathnameWithoutSplatRouteParams.tsx | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 packages/remix/src/client/usePathnameWithoutSplatRouteParams.tsx diff --git a/packages/remix/src/client/uiComponents.tsx b/packages/remix/src/client/uiComponents.tsx index 3c28d5e28fb..6534dc0c5d8 100644 --- a/packages/remix/src/client/uiComponents.tsx +++ b/packages/remix/src/client/uiComponents.tsx @@ -13,23 +13,24 @@ import type { SignUpProps, UserProfileProps, } from '@clerk/types'; -import { useLocation } from '@remix-run/react'; import React from 'react'; +import { usePathnameWithoutSplatRouteParams } from './usePathnameWithoutSplatRouteParams'; + // The assignment of UserProfile with BaseUserProfile props is used // to support the CustomPage functionality (eg UserProfile.Page) // Also the `typeof BaseUserProfile` is used to resolved the following error: // "The inferred type of 'UserProfile' cannot be named without a reference to ..." export const UserProfile: typeof BaseUserProfile = Object.assign( (props: UserProfileProps) => { - const { pathname: path } = useLocation(); + const path = usePathnameWithoutSplatRouteParams(); return ; }, { ...BaseUserProfile }, ); export const CreateOrganization = (props: CreateOrganizationProps) => { - const { pathname: path } = useLocation(); + const path = usePathnameWithoutSplatRouteParams(); return ; }; @@ -39,18 +40,18 @@ export const CreateOrganization = (props: CreateOrganizationProps) => { // "The inferred type of 'OrganizationProfile' cannot be named without a reference to ..." export const OrganizationProfile: typeof BaseOrganizationProfile = Object.assign( (props: OrganizationProfileProps) => { - const { pathname: path } = useLocation(); + const path = usePathnameWithoutSplatRouteParams(); return ; }, { ...BaseOrganizationProfile }, ); export const SignIn = (props: SignInProps) => { - const { pathname: path } = useLocation(); + const path = usePathnameWithoutSplatRouteParams(); return ; }; export const SignUp = (props: SignUpProps) => { - const { pathname: path } = useLocation(); + const path = usePathnameWithoutSplatRouteParams(); return ; }; diff --git a/packages/remix/src/client/usePathnameWithoutSplatRouteParams.tsx b/packages/remix/src/client/usePathnameWithoutSplatRouteParams.tsx new file mode 100644 index 00000000000..97cb85ca4f7 --- /dev/null +++ b/packages/remix/src/client/usePathnameWithoutSplatRouteParams.tsx @@ -0,0 +1,18 @@ +import { useLocation, useParams } from '@remix-run/react'; + +export const usePathnameWithoutSplatRouteParams = () => { + const params = useParams(); + const { pathname } = useLocation(); + + // Get the splat route params + // Remix store splat route params in an object with a key of '*' + // If there are no splat route params, we fallback to an empty string + const splatRouteParam = params['*'] || ''; + + // Remove the splat route param from the pathname + // so we end up with the pathname where the components are mounted at + // eg /user/123/profile/security will return /user/123/profile as the path + const path = pathname.replace(splatRouteParam, '').replace(/\/$/, '').replace(/^\//, '').trim(); + + return `/${path}`; +};