Skip to content
Open
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
22 changes: 22 additions & 0 deletions .changeset/nextjs-deprecate-route-matcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
'@clerk/nextjs': patch
---

Deprecate `createRouteMatcher()` in favor of resource-based auth checks.

Middleware-based auth checks rely on path matching, which can diverge from how Next.js routes requests and leave protected resources reachable.

For a migration guide, see:
https://clerk.com/docs/guides/development/upgrading/upgrade-guides/migrate-from-create-route-matcher

Instead of protecting routes from middleware, move auth checks into each protected page, layout, API route, or Server Function, for example:

```ts
import { auth } from '@clerk/nextjs/server'

export default async function Page() {
await auth.protect()

return <h1>Dashboard</h1>
}
```
26 changes: 26 additions & 0 deletions packages/nextjs/src/server/__tests__/routeMatcher.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { createRouteMatcher } from '../routeMatcher';

const { mockDeprecated } = vi.hoisted(() => ({
mockDeprecated: vi.fn(),
}));

vi.mock('@clerk/shared/deprecated', () => ({
deprecated: mockDeprecated,
}));

describe('createRouteMatcher', () => {
beforeEach(() => {
mockDeprecated.mockClear();
});

it('should emit a deprecation warning when called', () => {
createRouteMatcher(['/foo(.*)']);

expect(mockDeprecated).toHaveBeenCalledWith(
'createRouteMatcher',
'Use resource-based auth checks instead. Move auth checks into each page, layout, API route, or Server Function that accesses protected data. Middleware-based auth checks rely on path matching, which can diverge from how Next.js routes requests and leave protected resources reachable. For a migration guide, see: https://clerk.com/docs/guides/development/upgrading/upgrade-guides/migrate-from-create-route-matcher',
);
});
});
13 changes: 13 additions & 0 deletions packages/nextjs/src/server/routeMatcher.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { deprecated } from '@clerk/shared/deprecated';
import { createPathMatcher, type WithPathPatternWildcard } from '@clerk/shared/pathMatcher';
import type { Autocomplete } from '@clerk/shared/types';
import type Link from 'next/link';
Expand All @@ -19,8 +20,20 @@ export type RouteMatcherParam =
* You can use glob patterns to match multiple routes or a function to match against the request object.
* Path patterns and regular expressions are supported, for example: `['/foo', '/bar(.*)'] or `[/^\/foo\/.*$/]`
* For more information, see: https://clerk.com/docs
*
* @deprecated This function will be removed in the next major version. Use resource-based auth checks instead.
* Move auth checks into each page, layout, API route, or Server Function that accesses protected data.
* Middleware-based auth checks rely on path matching, which can diverge from how Next.js routes requests and
* leave protected resources reachable.
*
* For a migration guide, see:
* https://clerk.com/docs/guides/development/upgrading/upgrade-guides/migrate-from-create-route-matcher
*/
export const createRouteMatcher = (routes: RouteMatcherParam) => {
deprecated(
'createRouteMatcher',
'Use resource-based auth checks instead. Move auth checks into each page, layout, API route, or Server Function that accesses protected data. Middleware-based auth checks rely on path matching, which can diverge from how Next.js routes requests and leave protected resources reachable. For a migration guide, see: https://clerk.com/docs/guides/development/upgrading/upgrade-guides/migrate-from-create-route-matcher',
);
if (typeof routes === 'function') {
return (req: NextRequest) => routes(req);
}
Expand Down
Loading