diff --git a/.changeset/auth-misimport-runtime-error.md b/.changeset/auth-misimport-runtime-error.md new file mode 100644 index 00000000000..26355f119b8 --- /dev/null +++ b/.changeset/auth-misimport-runtime-error.md @@ -0,0 +1,5 @@ +--- +"@clerk/nextjs": patch +--- + +Improved error message when `auth` is accidentally imported from `@clerk/nextjs` instead of `@clerk/nextjs/server`. Previously, bundlers would show a generic `'auth' is not exported` error. Now, a clear runtime error points developers to the correct import path. diff --git a/packages/nextjs/src/__tests__/auth-misimport.test.ts b/packages/nextjs/src/__tests__/auth-misimport.test.ts new file mode 100644 index 00000000000..8e9f3813be1 --- /dev/null +++ b/packages/nextjs/src/__tests__/auth-misimport.test.ts @@ -0,0 +1,19 @@ +import { describe, expect, it } from 'vitest'; + +import { auth } from '../server-only-stubs'; + +describe('auth misimport from @clerk/nextjs', () => { + it('throws a descriptive error when called as a function', () => { + expect(() => (auth as unknown as () => void)()).toThrow("Clerk: auth() was imported from '@clerk/nextjs'"); + expect(() => (auth as unknown as () => void)()).toThrow("import { auth } from '@clerk/nextjs/server'"); + }); + + it('throws a descriptive error when accessing a property', () => { + expect(() => (auth as unknown as Record).protect).toThrow( + "Clerk: auth was imported from '@clerk/nextjs'", + ); + expect(() => (auth as unknown as Record).protect).toThrow( + "import { auth } from '@clerk/nextjs/server'", + ); + }); +}); diff --git a/packages/nextjs/src/index.ts b/packages/nextjs/src/index.ts index 283a7935cfc..18c5b686352 100644 --- a/packages/nextjs/src/index.ts +++ b/packages/nextjs/src/index.ts @@ -96,4 +96,4 @@ export const Show = ComponentsModule.Show as ServerComponentsServerModuleTypes[' * The `auth` function is only available in server-side contexts: * API Routes, Server Components, Server Actions, and Middleware. */ -export declare const auth: never; +export { auth } from './server-only-stubs'; diff --git a/packages/nextjs/src/server-only-stubs.ts b/packages/nextjs/src/server-only-stubs.ts new file mode 100644 index 00000000000..725e58c9b34 --- /dev/null +++ b/packages/nextjs/src/server-only-stubs.ts @@ -0,0 +1,18 @@ +/** + * Runtime stubs for server-only exports that are accidentally imported from the + * main `@clerk/nextjs` entry point. Each stub is a Proxy that throws a + * descriptive error pointing the developer to the correct import path. + */ + +export const auth: never = new Proxy((() => {}) as never, { + apply() { + throw new Error( + `Clerk: auth() was imported from '@clerk/nextjs'. The auth() helper is a server-side function and must be imported from '@clerk/nextjs/server'.\n\nTo fix this, update your import:\n import { auth } from '@clerk/nextjs/server'`, + ); + }, + get() { + throw new Error( + `Clerk: auth was imported from '@clerk/nextjs'. The auth() helper is a server-side function and must be imported from '@clerk/nextjs/server'.\n\nTo fix this, update your import:\n import { auth } from '@clerk/nextjs/server'`, + ); + }, +});