Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 468
feat(clerk-react,remix,nextjs): Make path the default routing strategy for NextJS and Remix#2338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
85a5f3e97a1ea6cd8ae3a7ca360e24c375af82b75b36fa16db41d612563f1e7File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| --- | ||
| '@clerk/clerk-js': major | ||
| '@clerk/nextjs': major | ||
| '@clerk/clerk-react': major | ||
| '@clerk/remix': major | ||
| --- | ||
| Path-based routing is now the default routing strategy if the `path` prop is filled. Additionally, if the `path` and `routing` props are not filled, an error will be thrown. | ||
| ```jsx | ||
| // Without path or routing props, an error with be thrown | ||
| <UserProfile /> | ||
| <CreateOrganization /> | ||
| <OrganizationProfile /> | ||
| <SignIn /> | ||
| <SignUp /> | ||
| // Alternative #1 | ||
| <UserProfile path="/whatever"/> | ||
| <CreateOrganization path="/whatever"/> | ||
| <OrganizationProfile path="/whatever"/> | ||
| <SignIn path="/whatever"/> | ||
| <SignUp path="/whatever"/> | ||
| // Alternative #2 | ||
| <UserProfile routing="hash_or_virtual"/> | ||
| <CreateOrganization routing="hash_or_virtual"/> | ||
| <OrganizationProfile routing="hash_or_virtual"/> | ||
| <SignIn routing="hash_or_virtual"/> | ||
| <SignUp routing="hash_or_virtual"/> | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,52 +1,52 @@ | ||
| 'use client'; | ||
| import { SignIn as BaseSignIn, SignUp as BaseSignUp } from '@clerk/clerk-react'; | ||
| import type { SignInProps, SignUpProps } from '@clerk/types'; | ||
| import { | ||
| CreateOrganization as BaseCreateOrganization, | ||
| OrganizationProfile as BaseOrganizationProfile, | ||
| SignIn as BaseSignIn, | ||
| SignUp as BaseSignUp, | ||
| UserProfile as BaseUserProfile, | ||
| } from '@clerk/clerk-react'; | ||
| import { useRoutingProps } from '@clerk/clerk-react/internal'; | ||
| import type { | ||
| CreateOrganizationProps, | ||
| OrganizationProfileProps, | ||
| SignInProps, | ||
| SignUpProps, | ||
| UserProfileProps, | ||
| } from '@clerk/types'; | ||
| import React from 'react'; | ||
| import { useClerkNextOptions } from './NextOptionsContext'; | ||
| export { | ||
| CreateOrganization, | ||
| OrganizationList, | ||
| OrganizationProfile, | ||
| OrganizationSwitcher, | ||
| SignInButton, | ||
| SignInWithMetamaskButton, | ||
| SignOutButton, | ||
| SignUpButton, | ||
| UserButton, | ||
| UserProfile, | ||
| } from '@clerk/clerk-react'; | ||
| export const UserProfile = (props: UserProfileProps) => { | ||
| return <BaseUserProfile {...useRoutingProps('UserProfile', props)} />; | ||
| }; | ||
| export const CreateOrganization = (props: CreateOrganizationProps) => { | ||
| return <BaseCreateOrganization {...useRoutingProps('CreateOrganization', props)} />; | ||
| }; | ||
| export const OrganizationProfile = (props: OrganizationProfileProps) => { | ||
| return <BaseOrganizationProfile {...useRoutingProps('OrganizationProfile', props)} />; | ||
| }; | ||
| export const SignIn = (props: SignInProps) => { | ||
| const { signInUrl: repoLevelSignInUrl } = useClerkNextOptions(); | ||
| const path = props.path || repoLevelSignInUrl; | ||
| if (path) { | ||
| <BaseSignIn | ||
| {...props} | ||
| routing='path' | ||
| path={path} | ||
| />; | ||
| } | ||
| return <BaseSignIn {...props} />; | ||
| const { signInUrl } = useClerkNextOptions(); | ||
| return <BaseSignIn {...useRoutingProps('SignIn', props, { path: signInUrl })} />; | ||
| }; | ||
| export const SignUp = (props: SignUpProps) => { | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that you're not using the HOC for the components that are mounted in paths we can infer using the env variables. I feel like we should align this behavior by either:
Do you want to discuss offline for possible solutions? :) Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ☝️ ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep I thought about that too, but the | ||
| const { signUpUrl: repoLevelSignUpUrl } = useClerkNextOptions(); | ||
| const path = props.path || repoLevelSignUpUrl; | ||
| if (path) { | ||
| return ( | ||
| <BaseSignUp | ||
| {...props} | ||
| routing='path' | ||
| path={path} | ||
| /> | ||
| ); | ||
| } | ||
| return <BaseSignUp {...props} />; | ||
| const { signUpUrl } = useClerkNextOptions(); | ||
| return <BaseSignUp {...useRoutingProps('SignUp', props, { path: signUpUrl })} />; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import type { RoutingOptions } from '@clerk/types'; | ||
| import { errorThrower } from '../errors/errorThrower'; | ||
| import { noPathProvidedError } from '../errors/messages'; | ||
| export function useRoutingProps<T extends RoutingOptions>( | ||
| componentName: string, | ||
| props: T, | ||
| routingOptions?: RoutingOptions, | ||
| ): T { | ||
| if (!props.path && !props.routing) { | ||
| errorThrower.throw(noPathProvidedError(componentName)); | ||
| } | ||
| if (props.path) { | ||
| return { | ||
| ...routingOptions, | ||
| ...props, | ||
| routing: 'path', | ||
| }; | ||
| } | ||
| return { | ||
| ...routingOptions, | ||
| ...props, | ||
| }; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| export { setErrorThrowerOptions } from './errors/errorThrower'; | ||
| export { MultisessionAppSupport } from './components/controlComponents'; | ||
| export { useRoutingProps } from './hooks/useRoutingProps'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,40 @@ | ||
| import { SignIn as BaseSignIn, SignUp as BaseSignUp } from '@clerk/clerk-react'; | ||
| import type { SignInProps, SignUpProps } from '@clerk/types'; | ||
| import { | ||
| CreateOrganization as BaseCreateOrganization, | ||
| OrganizationProfile as BaseOrganizationProfile, | ||
| SignIn as BaseSignIn, | ||
| SignUp as BaseSignUp, | ||
| UserProfile as BaseUserProfile, | ||
| } from '@clerk/clerk-react'; | ||
| import { useRoutingProps } from '@clerk/clerk-react/internal'; | ||
| import type { | ||
| CreateOrganizationProps, | ||
| OrganizationProfileProps, | ||
| SignInProps, | ||
| SignUpProps, | ||
| UserProfileProps, | ||
| } from '@clerk/types'; | ||
| import React from 'react'; | ||
| import { useClerkRemixOptions } from './RemixOptionsContext'; | ||
| export const SignIn = (props: SignInProps) => { | ||
| const { signInUrl } = useClerkRemixOptions(); | ||
| const path = props.path || signInUrl; | ||
| export const UserProfile = (props: UserProfileProps) => { | ||
| return <BaseUserProfile {...useRoutingProps('UserProfile', props)} />; | ||
| }; | ||
| if (path) { | ||
| return ( | ||
| <BaseSignIn | ||
| {...props} | ||
| routing='path' | ||
| path={path} | ||
| /> | ||
| ); | ||
| } | ||
| export const CreateOrganization = (props: CreateOrganizationProps) => { | ||
| return <BaseCreateOrganization {...useRoutingProps('CreateOrganization', props)} />; | ||
| }; | ||
| return <BaseSignIn {...props} />; | ||
| export const OrganizationProfile = (props: OrganizationProfileProps) => { | ||
| return <BaseOrganizationProfile {...useRoutingProps('OrganizationProfile', props)} />; | ||
| }; | ||
| export const SignIn = (props: SignInProps) => { | ||
| const { signInUrl } = useClerkRemixOptions(); | ||
| return <BaseSignIn {...useRoutingProps('SignIn', props, { path: signInUrl })} />; | ||
| }; | ||
| export const SignUp = (props: SignUpProps) => { | ||
| const { signUpUrl } = useClerkRemixOptions(); | ||
| const path = props.path || signUpUrl; | ||
| if (path) { | ||
| return ( | ||
| <BaseSignUp | ||
| routing='path' | ||
| path={path} | ||
| /> | ||
| ); | ||
| } | ||
| return <BaseSignUp {...props} />; | ||
| return <BaseSignUp {...useRoutingProps('SignUp', props, { path: signUpUrl })} />; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -7,7 +7,7 @@ const OrganizationProfilePage: NextPage = () => { | ||
| <div | ||
| style={{ display: 'flex', flexDirection: 'column', gap: '2rem', justifyContent: 'center', alignItems: 'center' }} | ||
| > | ||
| <OrganizationProfile /> | ||
| <OrganizationProfile path='/organization' /> | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❓ Will this error on dev time due to missing type? Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error will be shown when the component is being rendered. This is a runtime error | ||
| </div> | ||
| ); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SokratisVidros , @nikosdouvlis i have also added examples in changeset