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
36 changes: 36 additions & 0 deletions .changeset/green-humans-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
'@clerk/react-router': major
---

Usage of `rootAuthLoader` without the `clerkMiddleware()` installed will not throw a runtime error.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Fix inverted logic in breaking change description.

The statement says "will not throw a runtime error" but based on the PR objectives and AI summary, the code now requires clerkMiddleware() and throws when it is absent. This is the opposite of what's documented.

This is critical because users rely on changeset documentation to understand breaking changes during migration.

📝 Proposed fix
-Usage of `rootAuthLoader` without the `clerkMiddleware()` installed will not throw a runtime error.
+Usage of `rootAuthLoader` without the `clerkMiddleware()` installed will now throw a runtime error.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Usage of `rootAuthLoader` without the `clerkMiddleware()` installed will not throw a runtime error.
Usage of `rootAuthLoader` without the `clerkMiddleware()` installed will now throw a runtime error.
🤖 Prompt for AI Agents
In @.changeset/green-humans-yawn.md at line 5, The breaking-change sentence in
the changeset is inverted: update the description text so it correctly states
that using rootAuthLoader without installing clerkMiddleware() will now throw a
runtime error (i.e., the code requires clerkMiddleware()), referencing the
symbols rootAuthLoader and clerkMiddleware() so readers know the affected API;
replace the current "will not throw a runtime error" phrasing with a clear "will
throw a runtime error" explanation and, optionally, add a brief migration note
advising to install clerkMiddleware() where rootAuthLoader is used.


**Before (Removed):**

```tsx
import { rootAuthLoader } from '@clerk/react-router/ssr.server'

export const loader = (args: Route.LoaderArgs) => rootAuthLoader(args)
```

**After:**

1. Enable the `v8_middleware` future flag:

```ts
// react-router.config.ts
export default {
future: {
v8_middleware: true,
},
} satisfies Config;
```

2. Use the middleware in your app:

```tsx
import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server'

export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()]

export const loader = (args: Route.LoaderArgs) => rootAuthLoader(args)
```
170 changes: 0 additions & 170 deletions integration/tests/react-router/pre-middleware.test.ts

This file was deleted.

25 changes: 3 additions & 22 deletions packages/react-router/src/server/__tests__/getAuth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,14 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';

import { authFnContext } from '../clerkMiddleware';
import { getAuth } from '../getAuth';
import { legacyAuthenticateRequest } from '../legacyAuthenticateRequest';

vi.mock('../legacyAuthenticateRequest', () => {
return {
legacyAuthenticateRequest: vi.fn().mockResolvedValue({
toAuth: vi.fn().mockImplementation(() => ({
userId: 'user_xxx',
tokenType: TokenType.SessionToken,
})),
headers: new Headers(),
status: 'signed-in',
}),
};
});

describe('getAuth', () => {
beforeEach(() => {
vi.clearAllMocks();
process.env.CLERK_SECRET_KEY = 'sk_test_...';
});

it('should not call legacyAuthenticateRequest when middleware context exists', async () => {
it('should work when middleware context exists', async () => {
const mockContext = {
get: vi.fn().mockImplementation(contextKey => {
if (contextKey === authFnContext) {
Expand All @@ -47,12 +33,11 @@ describe('getAuth', () => {

const auth = await getAuth(args);

expect(legacyAuthenticateRequest).not.toHaveBeenCalled();
expect(auth.userId).toBe('user_xxx');
expect(auth.tokenType).toBe('session_token');
});

it('should call legacyAuthenticateRequest when middleware context is missing', async () => {
it('should throw an error when middleware context is missing', async () => {
const mockContext = {
get: vi.fn().mockReturnValue(null),
};
Expand All @@ -62,10 +47,6 @@ describe('getAuth', () => {
request: new Request('http://clerk.com'),
} as LoaderFunctionArgs;

const auth = await getAuth(args);

expect(legacyAuthenticateRequest).toHaveBeenCalled();
expect(auth.userId).toBe('user_xxx');
expect(auth.tokenType).toBe('session_token');
await expect(getAuth(args)).rejects.toThrow('Clerk: clerkMiddleware() not detected');
});
});
Loading
Loading