Skip to content

Commit 3aa63dc

Browse files
authored
feat(shared): Move ClerkRouter into shared (#4045)
1 parent 1369301 commit 3aa63dc

File tree

12 files changed

+36
-16
lines changed

12 files changed

+36
-16
lines changed

.changeset/quiet-lobsters-notice.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@clerk/shared": minor
3+
"@clerk/elements": patch
4+
---
5+
6+
Moves the common `ClerkRouter` interface into `@clerk/shared/router`. Elements has been refactored internally to import the router from the shared package.

packages/elements/src/internals/machines/types/router.types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { ClerkRouter } from '@clerk/shared/router';
12
import type {
23
ClerkResource,
34
LoadedClerk,
@@ -10,7 +11,6 @@ import type { ActorRefFrom } from 'xstate';
1011

1112
import type { ClerkElementsError } from '~/internals/errors';
1213
import type { TFormMachine } from '~/internals/machines/form';
13-
import type { ClerkRouter } from '~/react/router';
1414

1515
// ---------------------------------- Events ---------------------------------- //
1616

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
export { useNextRouter } from './next';
2-
export { Route, Router, useClerkRouter } from './react';
2+
export { Route, Router, useClerkRouter } from '@clerk/shared/router';
33
export { useVirtualRouter } from './virtual';
4-
5-
export type { ClerkRouter, ClerkHostRouter } from './router';

packages/elements/src/react/router/next.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1+
import type { ClerkHostRouter } from '@clerk/shared/router';
12
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
23

34
import { NEXT_WINDOW_HISTORY_SUPPORT_VERSION } from '~/internals/constants';
45

5-
import type { ClerkHostRouter } from './router';
6-
76
/**
87
* Clerk router integration with Next.js's router.
98
*/

packages/elements/src/react/router/virtual.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
'use client';
22

3+
import type { ClerkHostRouter } from '@clerk/shared/router';
34
import { useSyncExternalStore } from 'react';
45

5-
import type { ClerkHostRouter } from './router';
6-
76
const DUMMY_ORIGIN = 'https://clerk.dummy';
87

98
// TODO: introduce history stack?

packages/shared/src/router.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { type ClerkRouter, type ClerkHostRouter, createClerkRouter } from './router/router';
2+
export { type RoutingMode } from './router/types';
3+
export { Router, useClerkRouter, Route, ClerkRouterContext } from './router/react';

packages/elements/src/react/router/react.tsx packages/shared/src/router/react.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { createContext, useContext } from 'react';
1+
/**
2+
* React-specific binding's for interacting with Clerk's router interface.
3+
*/
4+
import React, { createContext, useContext } from 'react';
25

36
import type { ClerkHostRouter, ClerkRouter } from './router';
47
import { createClerkRouter } from './router';
@@ -15,6 +18,9 @@ export function useClerkRouter() {
1518
return ctx;
1619
}
1720

21+
/**
22+
* Construct a Clerk Router using the provided host router. The router instance is accessible using `useClerkRouter()`.
23+
*/
1824
export function Router({
1925
basePath,
2026
children,
@@ -31,8 +37,10 @@ export function Router({
3137

3238
type RouteProps = { path?: string; index?: boolean };
3339

40+
/**
41+
* Used to conditionally render its children based on whether or not the current path matches the provided path.
42+
*/
3443
export function Route({ path, children, index }: RouteProps & { children: React.ReactNode }) {
35-
// check for parent router, if exists, create child router, otherwise create one
3644
const parentRouter = useClerkRouter();
3745

3846
if (!path && !index) {

packages/elements/src/react/router/router.ts packages/shared/src/router/router.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import { withLeadingSlash, withoutTrailingSlash } from '@clerk/shared/url';
2-
3-
import type { ROUTING } from '~/internals/constants';
4-
import { isAbsoluteUrl } from '~/utils/is-absolute-url';
1+
import { isAbsoluteUrl, withLeadingSlash, withoutTrailingSlash } from '../url';
2+
import type { RoutingMode } from './types';
53

64
export const PRESERVED_QUERYSTRING_PARAMS = ['after_sign_in_url', 'after_sign_up_url', 'redirect_url'];
75

86
/**
97
* This type represents a generic router interface that Clerk relies on to interact with the host router.
108
*/
119
export type ClerkHostRouter = {
12-
readonly mode: ROUTING;
10+
readonly mode: RoutingMode;
1311
readonly name: string;
1412
pathname: () => string;
1513
push: (path: string) => void;
@@ -38,7 +36,7 @@ export type ClerkRouter = {
3836
/**
3937
* Mode of the router instance, path-based or virtual
4038
*/
41-
readonly mode: ROUTING;
39+
readonly mode: RoutingMode;
4240

4341
/**
4442
* Name of the router instance

packages/shared/src/router/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type RoutingMode = 'path' | 'virtual';

packages/shared/src/url.ts

+7
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,10 @@ export function joinURL(base: string, ...input: string[]): string {
170170

171171
return url;
172172
}
173+
174+
/* Code below is taken from https://github.com/vercel/next.js/blob/fe7ff3f468d7651a92865350bfd0f16ceba27db5/packages/next/src/shared/lib/utils.ts. LICENSE: MIT */
175+
176+
// Scheme: https://tools.ietf.org/html/rfc3986#section-3.1
177+
// Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3
178+
const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/;
179+
export const isAbsoluteUrl = (url: string) => ABSOLUTE_URL_REGEX.test(url);

packages/shared/subpaths.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const subpathNames = [
2929
'telemetry',
3030
'logger',
3131
'webauthn',
32+
'router',
3233
];
3334

3435
export const subpathFoldersBarrel = ['react'];

0 commit comments

Comments
 (0)