diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 3c6021db93fe8..a504a3b0e4bfc 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -850,7 +850,9 @@ export default async function build( ) const clientRouterFilters = createClientRouterFilter( appPageKeys, - nonInternalRedirects + config.experimental.clientRouterFilterRedirects + ? nonInternalRedirects + : [] ) NextBuildContext.clientRouterFilters = clientRouterFilters diff --git a/packages/next/src/lib/create-client-router-filter.ts b/packages/next/src/lib/create-client-router-filter.ts index 715e232943484..a1327f0626224 100644 --- a/packages/next/src/lib/create-client-router-filter.ts +++ b/packages/next/src/lib/create-client-router-filter.ts @@ -5,7 +5,7 @@ import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing- import { Redirect } from './load-custom-routes' import { tryToParsePath } from './try-to-parse-path' -const POTENTIAL_ERROR_RATE = 0.02 +const POTENTIAL_ERROR_RATE = 0.01 export function createClientRouterFilter( paths: string[], diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index 904ec224a1316..3136af5977f01 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -253,6 +253,9 @@ const configSchema = { clientRouterFilter: { type: 'boolean', }, + clientRouterFilterRedirects: { + type: 'boolean', + }, cpus: { type: 'number', }, diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index aa005fa0d8726..57dfb71451533 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -115,6 +115,7 @@ export interface NextJsWebpackConfig { export interface ExperimentalConfig { clientRouterFilter?: boolean + clientRouterFilterRedirects?: boolean externalMiddlewareRewritesResolve?: boolean extensionAlias?: Record allowedRevalidateHeaderKeys?: string[] @@ -621,6 +622,7 @@ export const defaultConfig: NextConfig = { modularizeImports: undefined, experimental: { clientRouterFilter: false, + clientRouterFilterRedirects: false, preCompiledNextServer: false, fetchCacheKeyPrefix: '', middlewarePrefetch: 'flexible', diff --git a/packages/next/src/server/dev/next-dev-server.ts b/packages/next/src/server/dev/next-dev-server.ts index 0e410e6ac014e..1ec8f5df4797c 100644 --- a/packages/next/src/server/dev/next-dev-server.ts +++ b/packages/next/src/server/dev/next-dev-server.ts @@ -585,9 +585,11 @@ export default class DevServer extends Server { if (this.nextConfig.experimental.clientRouterFilter) { clientRouterFilters = createClientRouterFilter( Object.keys(appPaths), - ((this.nextConfig as any)._originalRedirects || []).filter( - (r: any) => !r.internal - ) + this.nextConfig.experimental.clientRouterFilterRedirects + ? ((this.nextConfig as any)._originalRedirects || []).filter( + (r: any) => !r.internal + ) + : [] ) if ( diff --git a/packages/next/src/shared/lib/router/router.ts b/packages/next/src/shared/lib/router/router.ts index 0ef009460683e..a49f2a1aa5e91 100644 --- a/packages/next/src/shared/lib/router/router.ts +++ b/packages/next/src/shared/lib/router/router.ts @@ -1123,7 +1123,7 @@ export default class Router implements BaseRouter { // any time without notice. const isQueryUpdating = (options as any)._h === 1 - if (!isQueryUpdating) { + if (!isQueryUpdating && !options.shallow) { await this._bfl(as, undefined, options.locale) } @@ -1509,7 +1509,7 @@ export default class Router implements BaseRouter { isMiddlewareRewrite, }) - if (!isQueryUpdating) { + if (!isQueryUpdating && !options.shallow) { await this._bfl( as, 'resolvedAs' in routeInfo ? routeInfo.resolvedAs : undefined, diff --git a/test/e2e/app-dir/app-middleware/next.config.js b/test/e2e/app-dir/app-middleware/next.config.js index f9234a3d2492d..fbffedab5bdc3 100644 --- a/test/e2e/app-dir/app-middleware/next.config.js +++ b/test/e2e/app-dir/app-middleware/next.config.js @@ -2,5 +2,6 @@ module.exports = { experimental: { appDir: true, clientRouterFilter: true, + clientRouterFilterRedirects: true, }, } diff --git a/test/e2e/app-dir/app/index.test.ts b/test/e2e/app-dir/app/index.test.ts index ee0fe1b1181ed..9e3d2586a6132 100644 --- a/test/e2e/app-dir/app/index.test.ts +++ b/test/e2e/app-dir/app/index.test.ts @@ -70,6 +70,19 @@ createNextDescribe( } ) + it('should not apply client router filter on shallow', async () => { + const browser = await next.browser('/') + await browser.eval('window.beforeNav = 1') + + await check(async () => { + await browser.eval( + `window.next.router.push('/', '/redirect-1', { shallow: true })` + ) + return await browser.eval('window.location.pathname') + }, '/redirect-1') + expect(await browser.eval('window.beforeNav')).toBe(1) + }) + if (isDev) { it('should not have duplicate config warnings', async () => { await next.fetch('/') diff --git a/test/e2e/app-dir/app/next.config.js b/test/e2e/app-dir/app/next.config.js index 3567d603b9add..9b106f00521b8 100644 --- a/test/e2e/app-dir/app/next.config.js +++ b/test/e2e/app-dir/app/next.config.js @@ -1,6 +1,7 @@ module.exports = { experimental: { appDir: true, + clientRouterFilterRedirects: true, sri: { algorithm: 'sha256', }, diff --git a/test/e2e/middleware-redirects/app/next.config.js b/test/e2e/middleware-redirects/app/next.config.js index 1d2b55769aece..0108fd96b4395 100644 --- a/test/e2e/middleware-redirects/app/next.config.js +++ b/test/e2e/middleware-redirects/app/next.config.js @@ -5,6 +5,7 @@ module.exports = { }, experimental: { clientRouterFilter: true, + clientRouterFilterRedirects: true, }, redirects() { return [