Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lucky-trains-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/nextjs": patch
---

Add support for `basePath` config property
1 change: 1 addition & 0 deletions packages/nextjs/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
extends: ['@clerk/custom/browser', '@clerk/custom/typescript', '@clerk/custom/jest', '@clerk/custom/react'],
rules: {
'import/no-unresolved': ['error', { ignore: ['^#'] }],
'turbo/no-undeclared-env-vars': ['error', { allowList: ['__NEXT_ROUTER_BASEPATH'] }],
},
overrides: [
{
Expand Down
3 changes: 2 additions & 1 deletion packages/nextjs/src/app-router/client/useInternalNavFun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { usePathname } from 'next/navigation';
import { useCallback, useEffect, useTransition } from 'react';

import type { NextClerkProviderProps } from '../../types';
import { removeBasePath } from '../../utils/removeBasePath';

declare global {
interface Window {
Expand Down Expand Up @@ -55,7 +56,7 @@ export const useInternalNavFun = (props: {
// If the navigation is external (usually when navigating away from the component but still within the app),
// we should use the Next.js router to navigate as it will handle updating the URL and also
// fetching the new page if necessary.
routerNav(to);
routerNav(removeBasePath(to));
}
});
});
Expand Down
5 changes: 3 additions & 2 deletions packages/nextjs/src/pages/ClerkProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { NextClerkProviderProps } from '../types';
import { ClerkJSScript } from '../utils/clerk-js-script';
import { invalidateNextRouterCache } from '../utils/invalidateNextRouterCache';
import { mergeNextClerkPropsWithEnv } from '../utils/mergeNextClerkPropsWithEnv';
import { removeBasePath } from '../utils/removeBasePath';

setErrorThrowerOptions({ packageName: PACKAGE_NAME });
setClerkJsLoadingErrorPackageName(PACKAGE_NAME);
Expand All @@ -34,8 +35,8 @@ export function ClerkProvider({ children, ...props }: NextClerkProviderProps): J
};
}, []);

const navigate = (to: string) => push(to);
const replaceNavigate = (to: string) => replace(to);
const navigate = (to: string) => push(removeBasePath(to));
const replaceNavigate = (to: string) => replace(removeBasePath(to));
const mergedProps = mergeNextClerkPropsWithEnv({ ...props, routerPush: navigate, routerReplace: replaceNavigate });
// ClerkProvider automatically injects __clerk_ssr_state
// getAuth returns a user-facing authServerSideProps that hides __clerk_ssr_state
Expand Down
17 changes: 17 additions & 0 deletions packages/nextjs/src/utils/__tests__/removeBasePath.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { removeBasePath } from '../removeBasePath';

describe('removeBasePath', () => {
afterAll(() => {
process.env.__NEXT_ROUTER_BASEPATH = undefined;
});

it('should remove basePath from argument', () => {
process.env.__NEXT_ROUTER_BASEPATH = '/basePath';
expect(removeBasePath('/basePath/home')).toBe('/home');
});

it('should return argument unchanged when basePath is undefined', () => {
process.env.__NEXT_ROUTER_BASEPATH = undefined;
expect(removeBasePath('/basePath/home')).toBe('/basePath/home');
});
});
1 change: 1 addition & 0 deletions packages/nextjs/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './pathMatchers';
export * from './removeBasePath';
export * from './response';
export * from './serverRedirectWithAuth';
14 changes: 14 additions & 0 deletions packages/nextjs/src/utils/removeBasePath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Removes the Next.js basePath from the provided destination if set.
* @param to Destination route to navigate to
* @returns Destination without basePath, if set
*/
export function removeBasePath(to: string): string {
let destination = to;
const basePath = process.env.__NEXT_ROUTER_BASEPATH;
if (basePath && destination.startsWith(basePath)) {
destination = destination.slice(basePath.length);
}

return destination;
}
Loading