diff --git a/packages/next/shared/lib/router/router.ts b/packages/next/shared/lib/router/router.ts
index 6f718b7d1d26863..cc9e43dd9301b51 100644
--- a/packages/next/shared/lib/router/router.ts
+++ b/packages/next/shared/lib/router/router.ts
@@ -1456,15 +1456,13 @@ export default class Router implements BaseRouter {
// we don't attempt resolve asPath when we need to execute
// middleware as the resolving will occur server-side
- const isMiddlewareMatch = await matchesMiddleware({
- asPath: as,
- locale: nextState.locale,
- router: this,
- })
-
- if (options.shallow && isMiddlewareMatch) {
- pathname = this.pathname
- }
+ const isMiddlewareMatch =
+ !options.shallow &&
+ (await matchesMiddleware({
+ asPath: as,
+ locale: nextState.locale,
+ router: this,
+ }))
if (isQueryUpdating && isMiddlewareMatch) {
shouldResolveHref = false
diff --git a/test/e2e/middleware-shallow-link/app/middleware.js b/test/e2e/middleware-shallow-link/app/middleware.js
new file mode 100644
index 000000000000000..dd6b55cae5e94fc
--- /dev/null
+++ b/test/e2e/middleware-shallow-link/app/middleware.js
@@ -0,0 +1,9 @@
+import { NextResponse } from 'next/server'
+
+export async function middleware() {
+ return NextResponse.next()
+}
+
+export const config = {
+ matcher: '/(.*$)',
+}
diff --git a/test/e2e/middleware-shallow-link/app/pages/index.js b/test/e2e/middleware-shallow-link/app/pages/index.js
new file mode 100644
index 000000000000000..97b4c0b8699d66b
--- /dev/null
+++ b/test/e2e/middleware-shallow-link/app/pages/index.js
@@ -0,0 +1,26 @@
+import Link from 'next/link'
+import React from 'react'
+
+const Page = () => {
+ return (
+ <>
+
Content for page 1
+
+
+ Shallow push
+
+
+
+
+ Go to page 2
+
+
+ >
+ )
+}
+
+export default Page
diff --git a/test/e2e/middleware-shallow-link/app/pages/page2.js b/test/e2e/middleware-shallow-link/app/pages/page2.js
new file mode 100644
index 000000000000000..a8de1b6f668295d
--- /dev/null
+++ b/test/e2e/middleware-shallow-link/app/pages/page2.js
@@ -0,0 +1,25 @@
+import Link from 'next/link'
+import React from 'react'
+
+const Page = () => {
+ return (
+ <>
+ Content for page 2
+
+ Shallow replace
+
+
+
+
+ >
+ )
+}
+
+export default Page
diff --git a/test/e2e/middleware-shallow-link/index.test.ts b/test/e2e/middleware-shallow-link/index.test.ts
new file mode 100644
index 000000000000000..b97cc5ee955603c
--- /dev/null
+++ b/test/e2e/middleware-shallow-link/index.test.ts
@@ -0,0 +1,42 @@
+import { createNext, FileRef } from 'e2e-utils'
+import { NextInstance } from 'test/lib/next-modes/base'
+import webdriver from 'next-webdriver'
+import { join } from 'path'
+
+describe('browser-shallow-navigation', () => {
+ let next: NextInstance
+
+ beforeAll(async () => {
+ next = await createNext({
+ files: {
+ pages: new FileRef(join(__dirname, 'app/pages')),
+ 'middleware.js': new FileRef(join(__dirname, 'app/middleware.js')),
+ },
+ })
+ })
+
+ afterAll(() => next.destroy())
+
+ it('should render the correct page', async () => {
+ const browser = await webdriver(next.url, '/')
+
+ /// do shallow push
+ await browser.elementByCss('[data-next-shallow-push]').click()
+ await browser.waitForElementByCss('[data-next-page]')
+
+ // go to another page
+ await browser.elementByCss('[data-next-page]').click()
+ await browser.waitForElementByCss('[data-next-shallow-replace]')
+
+ // do shadow replace
+ await browser.elementByCss('[data-next-shallow-replace]').click()
+ await browser.waitForElementByCss('[data-go-back]')
+
+ // go back using history api
+ await browser.elementByCss('[data-go-back]').click()
+
+ // get page h1
+ let title = await browser.elementByCss('h1').text()
+ expect(title).toContain('Content for page 1')
+ })
+})