diff --git a/.changeset/tiny-forks-sit.md b/.changeset/tiny-forks-sit.md
new file mode 100644
index 0000000000..bd2899152d
--- /dev/null
+++ b/.changeset/tiny-forks-sit.md
@@ -0,0 +1,6 @@
+---
+'@clerk/clerk-react': minor
+'@clerk/types': minor
+---
+
+Update the TypeScript types of ``. If you use the `routerPush` prop you're now required to also provide the `routerReplace` prop (or other way around). You can also not provide them at all since both props are optional.
diff --git a/.github/workflows/ui-retheme-changes-reminder.yml b/.github/workflows/ui-retheme-changes-reminder.yml
index 0414f1056d..c78d12f76e 100644
--- a/.github/workflows/ui-retheme-changes-reminder.yml
+++ b/.github/workflows/ui-retheme-changes-reminder.yml
@@ -6,7 +6,13 @@ on:
- main
paths:
- 'packages/clerk-js/src/ui/**'
-
+ # files with matching `*.retheme.ts` retheme variant
+ - 'packages/localizations/src/en-US.ts'
+ - 'packages/localizations/src/index.ts'
+ - 'packages/types/src/appearance.ts'
+ - 'packages/types/src/clerk.ts'
+ - 'packages/types/src/index.ts'
+ - 'packages/types/src/localization.ts'
jobs:
check-changes:
runs-on: ubuntu-latest
diff --git a/.prettierignore b/.prettierignore
index 1b91423549..b52b1aa940 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -15,4 +15,6 @@ dist
examples
node_modules
package-lock.json
-playground
\ No newline at end of file
+playground
+packages/backend/tests/**/*.js
+/**/CHANGELOG.md
\ No newline at end of file
diff --git a/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx b/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx
index bd1814ee79..5b1662c8b0 100644
--- a/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx
+++ b/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx
@@ -224,4 +224,23 @@ describe('ClerkProvider', () => {
expectTypeOf({ publishableKey: 'test' }).not.toMatchTypeOf();
});
});
+
+ describe('navigation options', () => {
+ it('expects both routerPush & routerReplace to pass', () => {
+ expectTypeOf({
+ publishableKey: 'test',
+ children: '',
+ routerPush: () => {},
+ routerReplace: () => {},
+ }).toMatchTypeOf();
+ });
+
+ it('errors if one of routerPush / routerReplace is passed', () => {
+ expectTypeOf({
+ publishableKey: 'test',
+ children: '',
+ routerPush: () => {},
+ }).not.toMatchTypeOf();
+ });
+ });
});
diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts
index 68b31e3ca0..d88e9fe0f3 100644
--- a/packages/react/src/types.ts
+++ b/packages/react/src/types.ts
@@ -11,6 +11,7 @@ import type {
SignInRedirectOptions,
SignUpRedirectOptions,
UserResource,
+ Without,
} from '@clerk/types';
import type React from 'react';
@@ -23,7 +24,7 @@ declare global {
}
}
-export type IsomorphicClerkOptions = Omit & {
+export type IsomorphicClerkOptions = Without & {
Clerk?: ClerkProp;
clerkJSUrl?: string;
clerkJSVariant?: 'headless' | '';
@@ -37,19 +38,10 @@ export type ClerkProviderProps = IsomorphicClerkOptions & {
initialState?: InitialState;
};
-// TODO(@dimkl): replacing it with the following make nextjs type tests fail
-// `Exclude & { publishableKey?: string }`
-// find another way to reduce the duplication.
-export type ClerkProviderOptionsWrapper = Omit & {
- Clerk?: ClerkProp;
- clerkJSUrl?: string;
- clerkJSVariant?: 'headless' | '';
- clerkJSVersion?: string;
- sdkMetadata?: SDKMetadata;
+export type ClerkProviderOptionsWrapper = Without & {
publishableKey?: string;
-} & MultiDomainAndOrProxy & {
- children: React.ReactNode;
- };
+ children: React.ReactNode;
+};
export interface BrowserClerkConstructor {
new (publishableKey: string, options?: DomainOrProxyUrl): BrowserClerk;
@@ -75,7 +67,7 @@ export interface MountProps {
}
export interface HeadlessBrowserClerk extends Clerk {
- load: (opts?: Omit) => Promise;
+ load: (opts?: Without) => Promise;
updateClient: (client: ClientResource) => void;
}
diff --git a/packages/types/src/clerk.retheme.ts b/packages/types/src/clerk.retheme.ts
index ee0b376398..691c180722 100644
--- a/packages/types/src/clerk.retheme.ts
+++ b/packages/types/src/clerk.retheme.ts
@@ -495,7 +495,25 @@ export type CustomNavigation = (to: string, options?: NavigateOptions) => Promis
export type ClerkThemeOptions = DeepSnakeToCamel>;
-export interface ClerkOptions {
+/**
+ * Navigation options used to replace or push history changes.
+ * Both `routerPush` & `routerReplace` OR none options should be passed.
+ */
+type ClerkOptionsNavigationFn =
+ | {
+ routerPush?: never;
+ routerReplace?: never;
+ }
+ | {
+ routerPush: (to: string) => Promise | unknown;
+ routerReplace: (to: string) => Promise | unknown;
+ };
+
+type ClerkOptionsNavigation = ClerkOptionsNavigationFn & {
+ routerDebug?: boolean;
+};
+
+export type ClerkOptions = ClerkOptionsNavigation & {
appearance?: Appearance;
localization?: LocalizationResource;
/**
@@ -535,7 +553,7 @@ export interface ClerkOptions {
};
sdkMetadata?: SDKMetadata;
-}
+};
export interface NavigateOptions {
replace?: boolean;
diff --git a/packages/types/src/clerk.ts b/packages/types/src/clerk.ts
index 1bf9181372..fca95e92fd 100644
--- a/packages/types/src/clerk.ts
+++ b/packages/types/src/clerk.ts
@@ -495,16 +495,27 @@ export type CustomNavigation = (to: string, options?: NavigateOptions) => Promis
export type ClerkThemeOptions = DeepSnakeToCamel>;
-export interface ClerkOptions {
- appearance?: Appearance;
- localization?: LocalizationResource;
- /**
- * Navigation
- */
- routerPush?: (to: string) => Promise | unknown;
- routerReplace?: (to: string) => Promise | unknown;
+/**
+ * Navigation options used to replace or push history changes.
+ * Both `routerPush` & `routerReplace` OR none options should be passed.
+ */
+type ClerkOptionsNavigationFn =
+ | {
+ routerPush?: never;
+ routerReplace?: never;
+ }
+ | {
+ routerPush: (to: string) => Promise | unknown;
+ routerReplace: (to: string) => Promise | unknown;
+ };
+
+type ClerkOptionsNavigation = ClerkOptionsNavigationFn & {
routerDebug?: boolean;
+};
+export type ClerkOptions = ClerkOptionsNavigation & {
+ appearance?: Appearance;
+ localization?: LocalizationResource;
polling?: boolean;
selectInitialSession?: (client: ClientResource) => ActiveSessionResource | null;
/** Controls if ClerkJS will load with the standard browser setup using Clerk cookies */
@@ -536,7 +547,7 @@ export interface ClerkOptions {
};
sdkMetadata?: SDKMetadata;
-}
+};
export interface NavigateOptions {
replace?: boolean;