Skip to content

Commit ae8891e

Browse files
committed
Skip internal routes in middleware
1 parent b5eba8f commit ae8891e

File tree

8 files changed

+44
-12
lines changed

8 files changed

+44
-12
lines changed

packages/next/src/build/entries.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
isInstrumentationHookFilename,
4646
} from './utils'
4747
import { getPageStaticInfo } from './analysis/get-page-static-info'
48+
import { getDefaultMiddlewareMatcher } from '../shared/lib/router/utils/get-default-middleware-matcher'
4849
import { normalizePathSep } from '../shared/lib/page-path/normalize-path-sep'
4950
import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path'
5051
import type { ServerRuntime } from '../types'
@@ -898,7 +899,7 @@ export async function createEntrypoints(
898899

899900
if (isMiddlewareFile(page)) {
900901
middlewareMatchers = staticInfo.middleware?.matchers ?? [
901-
{ regexp: '.*', originalSource: '/:path*' },
902+
getDefaultMiddlewareMatcher(params.config),
902903
]
903904
}
904905

packages/next/src/build/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ import { isEdgeRuntime } from '../lib/is-edge-runtime'
150150
import { recursiveCopy } from '../lib/recursive-copy'
151151
import { lockfilePatchPromise, teardownTraceSubscriber } from './swc'
152152
import { getNamedRouteRegex } from '../shared/lib/router/utils/route-regex'
153+
import { getDefaultMiddlewareMatcher } from '../shared/lib/router/utils/get-default-middleware-matcher'
153154
import { getFilesInDir } from '../lib/get-files-in-dir'
154155
import { eventSwcPlugins } from '../telemetry/events/swc-plugins'
155156
import { normalizeAppPath } from '../shared/lib/router/utils/app-paths'
@@ -2580,10 +2581,7 @@ export default async function build(
25802581
functionsConfigManifest.functions['/_middleware'] = {
25812582
runtime: staticInfo.runtime,
25822583
matchers: staticInfo.middleware?.matchers ?? [
2583-
{
2584-
regexp: '^.*$',
2585-
originalSource: '/:path*',
2586-
},
2584+
getDefaultMiddlewareMatcher(config),
25872585
],
25882586
}
25892587

packages/next/src/server/config-schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ export const configSchema: zod.ZodType<NextConfig> = z.lazy(() =>
676676
serverExternalPackages: z.array(z.string()).optional(),
677677
serverRuntimeConfig: z.record(z.string(), z.any()).optional(),
678678
skipMiddlewareUrlNormalize: z.boolean().optional(),
679+
skipMiddlewareNextInternalRoutes: z.boolean().optional(),
679680
skipTrailingSlashRedirect: z.boolean().optional(),
680681
staticPageGenerationTimeout: z.number().optional(),
681682
expireTime: z.number().optional(),

packages/next/src/server/config-shared.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,12 @@ export interface NextConfig {
12361236

12371237
skipMiddlewareUrlNormalize?: boolean
12381238

1239+
/**
1240+
* Skip Next.js internals route `/_next` from middleware.
1241+
* @default true
1242+
*/
1243+
skipMiddlewareNextInternalRoutes?: boolean
1244+
12391245
skipTrailingSlashRedirect?: boolean
12401246

12411247
modularizeImports?: Record<
@@ -1515,6 +1521,7 @@ export const defaultConfig = Object.freeze({
15151521
},
15161522
htmlLimitedBots: undefined,
15171523
bundlePagesRouterDependencies: false,
1524+
skipMiddlewareNextInternalRoutes: true,
15181525
} satisfies NextConfig)
15191526

15201527
export async function normalizeConfig(phase: string, config: any) {

packages/next/src/server/lib/router-utils/filesystem.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { pathHasPrefix } from '../../../shared/lib/router/utils/path-has-prefix'
3131
import { normalizeLocalePath } from '../../../shared/lib/i18n/normalize-locale-path'
3232
import { removePathPrefix } from '../../../shared/lib/router/utils/remove-path-prefix'
3333
import { getMiddlewareRouteMatcher } from '../../../shared/lib/router/utils/middleware-route-matcher'
34+
import { getDefaultMiddlewareMatcher } from '../../../shared/lib/router/utils/get-default-middleware-matcher'
3435
import {
3536
APP_PATH_ROUTES_MANIFEST,
3637
BUILD_ID_FILE,
@@ -314,7 +315,7 @@ export async function setupFsCheck(opts: {
314315
} else if (functionsConfigManifest?.functions['/_middleware']) {
315316
middlewareMatcher = getMiddlewareRouteMatcher(
316317
functionsConfigManifest.functions['/_middleware'].matchers ?? [
317-
{ regexp: '.*', originalSource: '/:path*' },
318+
getDefaultMiddlewareMatcher(opts.config),
318319
]
319320
)
320321
}

packages/next/src/server/lib/router-utils/setup-dev-bundler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
} from '../../../shared/lib/constants'
4949

5050
import { getMiddlewareRouteMatcher } from '../../../shared/lib/router/utils/middleware-route-matcher'
51+
import { getDefaultMiddlewareMatcher } from '../../../shared/lib/router/utils/get-default-middleware-matcher'
5152

5253
import {
5354
isMiddlewareFile,
@@ -472,7 +473,7 @@ async function startWatcher(
472473
serverFields.actualMiddlewareFile
473474
)
474475
middlewareMatchers = staticInfo.middleware?.matchers || [
475-
{ regexp: '^/.*$', originalSource: '/:path*' },
476+
getDefaultMiddlewareMatcher(opts.nextConfig),
476477
]
477478
continue
478479
}

packages/next/src/server/next-server.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import type { LoadComponentsReturnType } from './load-components'
7171
import isError, { getProperError } from '../lib/is-error'
7272
import { splitCookiesString, toNodeOutgoingHttpHeaders } from './web/utils'
7373
import { getMiddlewareRouteMatcher } from '../shared/lib/router/utils/middleware-route-matcher'
74+
import { getDefaultMiddlewareMatcher } from '../shared/lib/router/utils/get-default-middleware-matcher'
7475
import { loadEnvConfig } from '@next/env'
7576
import { urlQueryToSearchParams } from '../shared/lib/router/utils/querystring'
7677
import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-slash'
@@ -1455,13 +1456,13 @@ export default class NextNodeServer extends BaseServer<
14551456
const middlewareModule = await this.loadNodeMiddleware()
14561457

14571458
if (middlewareModule) {
1459+
const matchers = middlewareModule.config?.matchers || [
1460+
getDefaultMiddlewareMatcher(this.nextConfig),
1461+
]
14581462
return {
1459-
match: getMiddlewareRouteMatcher(
1460-
middlewareModule.config?.matchers || [
1461-
{ regexp: '.*', originalSource: '/:path*' },
1462-
]
1463-
),
1463+
match: getMiddlewareRouteMatcher(matchers),
14641464
page: '/',
1465+
matchers,
14651466
}
14661467
}
14671468

@@ -1471,6 +1472,7 @@ export default class NextNodeServer extends BaseServer<
14711472
return {
14721473
match: getMiddlewareMatcher(middleware),
14731474
page: '/',
1475+
matchers: middleware.matchers,
14741476
}
14751477
}
14761478

@@ -1679,6 +1681,7 @@ export default class NextNodeServer extends BaseServer<
16791681
return { finished: false }
16801682
}
16811683

1684+
16821685
await this.ensureMiddleware(params.request.url)
16831686
const middlewareInfo = this.getEdgeFunctionInfo({
16841687
page: middleware.page,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { MiddlewareMatcher } from '../../../../build/analysis/get-page-static-info'
2+
3+
export function getDefaultMiddlewareMatcher(config?: {
4+
skipMiddlewareNextInternalRoutes?: boolean
5+
}): MiddlewareMatcher {
6+
const skipInternal = config?.skipMiddlewareNextInternalRoutes !== false
7+
8+
if (skipInternal) {
9+
// Match everything except /_next/* (but still match /_next/data/* because it is used for client navigation)
10+
return {
11+
regexp: '^(?!\\/_next\\/(?!data\\/)).*',
12+
originalSource: '/:path*',
13+
}
14+
}
15+
16+
return {
17+
regexp: '.*',
18+
originalSource: '/:path*',
19+
}
20+
}

0 commit comments

Comments
 (0)