+ )
+}
diff --git a/test/production/app-dir/parallel-routes-prefetching/app/[letter]/loading.tsx b/test/production/app-dir/parallel-routes-prefetching/app/[letter]/loading.tsx
new file mode 100644
index 0000000000000..127f6a1255ee7
--- /dev/null
+++ b/test/production/app-dir/parallel-routes-prefetching/app/[letter]/loading.tsx
@@ -0,0 +1,3 @@
+export default function Loading() {
+ return
Loading
+}
diff --git a/test/production/app-dir/parallel-routes-prefetching/app/[letter]/page.tsx b/test/production/app-dir/parallel-routes-prefetching/app/[letter]/page.tsx
new file mode 100644
index 0000000000000..eee824bf3f46d
--- /dev/null
+++ b/test/production/app-dir/parallel-routes-prefetching/app/[letter]/page.tsx
@@ -0,0 +1,8 @@
+export default async function LetterPage({
+ params: { letter },
+}: {
+ params: { letter: string }
+}) {
+ await new Promise((r) => setTimeout(r, 250))
+ return
{letter}
+}
diff --git a/test/production/app-dir/parallel-routes-prefetching/app/layout.tsx b/test/production/app-dir/parallel-routes-prefetching/app/layout.tsx
new file mode 100644
index 0000000000000..e7077399c03ce
--- /dev/null
+++ b/test/production/app-dir/parallel-routes-prefetching/app/layout.tsx
@@ -0,0 +1,7 @@
+export default function Root({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ )
+}
diff --git a/test/production/app-dir/parallel-routes-prefetching/app/page.tsx b/test/production/app-dir/parallel-routes-prefetching/app/page.tsx
new file mode 100644
index 0000000000000..aebfb306b399e
--- /dev/null
+++ b/test/production/app-dir/parallel-routes-prefetching/app/page.tsx
@@ -0,0 +1,5 @@
+import Link from 'next/link'
+
+export default function Page() {
+ return Go to a letter
+}
diff --git a/test/production/app-dir/parallel-routes-prefetching/next.config.js b/test/production/app-dir/parallel-routes-prefetching/next.config.js
new file mode 100644
index 0000000000000..807126e4cf0bf
--- /dev/null
+++ b/test/production/app-dir/parallel-routes-prefetching/next.config.js
@@ -0,0 +1,6 @@
+/**
+ * @type {import('next').NextConfig}
+ */
+const nextConfig = {}
+
+module.exports = nextConfig
diff --git a/test/production/app-dir/parallel-routes-prefetching/parallel-routes-prefetching.test.ts b/test/production/app-dir/parallel-routes-prefetching/parallel-routes-prefetching.test.ts
new file mode 100644
index 0000000000000..803034396da9e
--- /dev/null
+++ b/test/production/app-dir/parallel-routes-prefetching/parallel-routes-prefetching.test.ts
@@ -0,0 +1,58 @@
+import { nextTestSetup } from 'e2e-utils'
+import { retry } from 'next-test-utils'
+
+describe('parallel-routes-prefetching', () => {
+ const { next } = nextTestSetup({
+ files: __dirname,
+ })
+
+ it('should not re-fetch data for the __DEFAULT__ segments when navigating within a dynamic segment', async () => {
+ let prefetchRequests = []
+ let rscRequests = []
+ const browser = await next.browser('/a', {
+ beforePageLoad(page) {
+ page.on('request', (request) => {
+ return request.allHeaders().then((headers) => {
+ if (headers['Next-Router-Prefetch'.toLowerCase()] === '1') {
+ prefetchRequests.push(request.url())
+ } else if (headers['RSC'.toLowerCase()] === '1') {
+ rscRequests.push(request.url())
+ }
+ })
+ })
+ },
+ })
+
+ expect(await browser.elementById('letter-page').text()).toBe('a')
+ expect(await browser.elementById('letter-parallel').text()).toBe('a')
+
+ await retry(() => {
+ // we should see 25 prefetch requests for each letter of the alphabet (excluding the current)
+ expect(prefetchRequests).toHaveLength(25)
+ // and 0 RSC requests since we're not navigating to a different dynamic segment
+ expect(rscRequests).toHaveLength(0)
+ })
+
+ prefetchRequests = []
+
+ await browser.elementByCss('[href="/b"]').click()
+
+ await retry(() => {
+ // Navigating to a new dynamic segment should trigger any additional prefetch requests
+ expect(prefetchRequests).toHaveLength(0)
+
+ // but we except 2 RSC requests for the new page:
+ // - one for the `children` slot
+ // - one for the active parallel slot
+ // TODO: It would be nice to achieve this in a single request, but it currently isn't possible,
+ // because the router will see missing data for both slots simultaneously and kick off two separate requests.
+ // PPR doesn't have this issue because it doesn't perform the "lazy fetch" in layout-router.
+ expect(rscRequests).toHaveLength(
+ process.env.__NEXT_EXPERIMENTAL_PPR ? 1 : 2
+ )
+ })
+
+ expect(await browser.elementById('letter-page').text()).toBe('b')
+ expect(await browser.elementById('letter-parallel').text()).toBe('b')
+ })
+})