From f96c362eaffa9b15eb401b20b67c27eb12fc2ceb Mon Sep 17 00:00:00 2001
From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Date: Wed, 8 Oct 2025 12:11:25 +0200
Subject: [PATCH 01/10] Extend tests
---
test/e2e/url/app/api/route.js | 6 +
test/e2e/url/app/client/page.js | 11 ++
test/e2e/url/app/layout.js | 7 +
test/e2e/url/app/manifest.js | 15 +++
test/e2e/url/app/rsc/page.js | 9 ++
test/e2e/url/middleware.ts | 13 ++
.../e2e/url/pages/api/{ => pages}/basename.js | 2 +-
test/e2e/url/pages/api/{ => pages}/size.js | 2 +-
test/e2e/url/pages/pages/ssg.js | 15 +++
test/e2e/url/pages/pages/ssr.js | 15 +++
test/e2e/url/pages/pages/static.js | 9 ++
test/e2e/url/pages/ssg.js | 15 ---
test/e2e/url/pages/ssr.js | 15 ---
test/e2e/url/pages/static.js | 9 --
test/e2e/url/url.test.ts | 123 ++++++++++++++----
15 files changed, 198 insertions(+), 68 deletions(-)
create mode 100644 test/e2e/url/app/api/route.js
create mode 100644 test/e2e/url/app/client/page.js
create mode 100644 test/e2e/url/app/layout.js
create mode 100644 test/e2e/url/app/manifest.js
create mode 100644 test/e2e/url/app/rsc/page.js
create mode 100644 test/e2e/url/middleware.ts
rename test/e2e/url/pages/api/{ => pages}/basename.js (63%)
rename test/e2e/url/pages/api/{ => pages}/size.js (61%)
create mode 100644 test/e2e/url/pages/pages/ssg.js
create mode 100644 test/e2e/url/pages/pages/ssr.js
create mode 100644 test/e2e/url/pages/pages/static.js
delete mode 100644 test/e2e/url/pages/ssg.js
delete mode 100644 test/e2e/url/pages/ssr.js
delete mode 100644 test/e2e/url/pages/static.js
diff --git a/test/e2e/url/app/api/route.js b/test/e2e/url/app/api/route.js
new file mode 100644
index 00000000000000..8e7a6b6dfd49e9
--- /dev/null
+++ b/test/e2e/url/app/api/route.js
@@ -0,0 +1,6 @@
+import imported from '../../public/vercel.png'
+const url = new URL('../../public/vercel.png', import.meta.url).toString()
+
+export function GET(req, res) {
+ return Response.json({ imported, url })
+}
diff --git a/test/e2e/url/app/client/page.js b/test/e2e/url/app/client/page.js
new file mode 100644
index 00000000000000..e1fddf79c865bc
--- /dev/null
+++ b/test/e2e/url/app/client/page.js
@@ -0,0 +1,11 @@
+'use client'
+
+const url = new URL('../../public/vercel.png', import.meta.url).pathname
+
+export default function Index(props) {
+ return (
+
+ Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+
+ )
+}
diff --git a/test/e2e/url/app/layout.js b/test/e2e/url/app/layout.js
new file mode 100644
index 00000000000000..4ee00a218505ac
--- /dev/null
+++ b/test/e2e/url/app/layout.js
@@ -0,0 +1,7 @@
+export default function RootLayout({ children }) {
+ return (
+
+
{children}
+
+ )
+}
diff --git a/test/e2e/url/app/manifest.js b/test/e2e/url/app/manifest.js
new file mode 100644
index 00000000000000..544ecf4c6fbc63
--- /dev/null
+++ b/test/e2e/url/app/manifest.js
@@ -0,0 +1,15 @@
+import icon from '../public/vercel.png'
+
+export default function manifest() {
+ return {
+ short_name: 'Next.js',
+ name: 'Next.js',
+ icons: [
+ {
+ src: icon.src,
+ type: 'image/png',
+ sizes: '512x512',
+ },
+ ],
+ }
+}
diff --git a/test/e2e/url/app/rsc/page.js b/test/e2e/url/app/rsc/page.js
new file mode 100644
index 00000000000000..3db56282512a5b
--- /dev/null
+++ b/test/e2e/url/app/rsc/page.js
@@ -0,0 +1,9 @@
+const url = new URL('../../public/vercel.png', import.meta.url).pathname
+
+export default function Index(props) {
+ return (
+
+ Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+
+ )
+}
diff --git a/test/e2e/url/middleware.ts b/test/e2e/url/middleware.ts
new file mode 100644
index 00000000000000..bf4ab3bcaa383e
--- /dev/null
+++ b/test/e2e/url/middleware.ts
@@ -0,0 +1,13 @@
+import { NextRequest, NextResponse } from 'next/server'
+
+// @ts-ignore
+import imported from './public/vercel.png'
+const url = new URL('./public/vercel.png', import.meta.url)
+
+export async function middleware(req: NextRequest) {
+ if (req.nextUrl.pathname === '/middleware') {
+ return Response.json({ imported, url })
+ }
+
+ return NextResponse.next()
+}
diff --git a/test/e2e/url/pages/api/basename.js b/test/e2e/url/pages/api/pages/basename.js
similarity index 63%
rename from test/e2e/url/pages/api/basename.js
rename to test/e2e/url/pages/api/pages/basename.js
index 0109c99b7b8819..22104403c5bcaf 100644
--- a/test/e2e/url/pages/api/basename.js
+++ b/test/e2e/url/pages/api/pages/basename.js
@@ -1,6 +1,6 @@
import path from 'path'
-const img = new URL('../../public/vercel.png', import.meta.url)
+const img = new URL('../../../public/vercel.png', import.meta.url)
export default (req, res) => {
res.json({ basename: path.posix.basename(img.pathname) })
diff --git a/test/e2e/url/pages/api/size.js b/test/e2e/url/pages/api/pages/size.js
similarity index 61%
rename from test/e2e/url/pages/api/size.js
rename to test/e2e/url/pages/api/pages/size.js
index 7649a0bcb1307b..2e961a4dcd5a43 100644
--- a/test/e2e/url/pages/api/size.js
+++ b/test/e2e/url/pages/api/pages/size.js
@@ -1,6 +1,6 @@
import fs from 'fs'
-const img = new URL('../../public/vercel.png', import.meta.url)
+const img = new URL('../../../public/vercel.png', import.meta.url)
export default (req, res) => {
res.json({ size: fs.readFileSync(img).length })
diff --git a/test/e2e/url/pages/pages/ssg.js b/test/e2e/url/pages/pages/ssg.js
new file mode 100644
index 00000000000000..d6a4221eb23abf
--- /dev/null
+++ b/test/e2e/url/pages/pages/ssg.js
@@ -0,0 +1,15 @@
+export async function getStaticProps() {
+ return {
+ props: {
+ url: new URL('../../public/vercel.png', import.meta.url).pathname,
+ },
+ }
+}
+
+export default function Index({ url }) {
+ return (
+
+ Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+
+ )
+}
diff --git a/test/e2e/url/pages/pages/ssr.js b/test/e2e/url/pages/pages/ssr.js
new file mode 100644
index 00000000000000..d2ce01363cec01
--- /dev/null
+++ b/test/e2e/url/pages/pages/ssr.js
@@ -0,0 +1,15 @@
+export function getServerSideProps() {
+ return {
+ props: {
+ url: new URL('../../public/vercel.png', import.meta.url).pathname,
+ },
+ }
+}
+
+export default function Index({ url }) {
+ return (
+
+ Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+
+ )
+}
diff --git a/test/e2e/url/pages/pages/static.js b/test/e2e/url/pages/pages/static.js
new file mode 100644
index 00000000000000..3db56282512a5b
--- /dev/null
+++ b/test/e2e/url/pages/pages/static.js
@@ -0,0 +1,9 @@
+const url = new URL('../../public/vercel.png', import.meta.url).pathname
+
+export default function Index(props) {
+ return (
+
+ Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+
+ )
+}
diff --git a/test/e2e/url/pages/ssg.js b/test/e2e/url/pages/ssg.js
deleted file mode 100644
index 113f47c56552f6..00000000000000
--- a/test/e2e/url/pages/ssg.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export async function getStaticProps() {
- return {
- props: {
- url: new URL('../public/vercel.png', import.meta.url).pathname,
- },
- }
-}
-
-export default function Index({ url }) {
- return (
-
- Hello {new URL('../public/vercel.png', import.meta.url).pathname}+{url}
-
- )
-}
diff --git a/test/e2e/url/pages/ssr.js b/test/e2e/url/pages/ssr.js
deleted file mode 100644
index 6aec1e94a0f725..00000000000000
--- a/test/e2e/url/pages/ssr.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export function getServerSideProps() {
- return {
- props: {
- url: new URL('../public/vercel.png', import.meta.url).pathname,
- },
- }
-}
-
-export default function Index({ url }) {
- return (
-
- Hello {new URL('../public/vercel.png', import.meta.url).pathname}+{url}
-
- )
-}
diff --git a/test/e2e/url/pages/static.js b/test/e2e/url/pages/static.js
deleted file mode 100644
index 03bc185ce9f08b..00000000000000
--- a/test/e2e/url/pages/static.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const url = new URL('../public/vercel.png', import.meta.url).pathname
-
-export default function Index(props) {
- return (
-
- Hello {new URL('../public/vercel.png', import.meta.url).pathname}+{url}
-
- )
-}
diff --git a/test/e2e/url/url.test.ts b/test/e2e/url/url.test.ts
index 7a11eff4aaa658..cfa397bed816db 100644
--- a/test/e2e/url/url.test.ts
+++ b/test/e2e/url/url.test.ts
@@ -1,4 +1,4 @@
-import { getBrowserBodyText, retry } from 'next-test-utils'
+import { retry } from 'next-test-utils'
import { nextTestSetup } from 'e2e-utils'
describe(`Handle new URL asset references`, () => {
@@ -6,41 +6,110 @@ describe(`Handle new URL asset references`, () => {
files: __dirname,
})
- const expectedServer =
- /Hello \/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png/
- const expectedClient = new RegExp(
- expectedServer.source.replace(//g, '')
- )
-
- for (const page of ['/static', '/ssr', '/ssg']) {
- it(`should render the ${page} page`, async () => {
- const html = await next.render(page)
- expect(html).toMatch(expectedServer)
- })
-
- it(`should client-render the ${page} page`, async () => {
- const browser = await next.browser(page)
- await retry(async () =>
- expect(await getBrowserBodyText(browser)).toMatch(expectedClient)
- )
- })
- }
-
- it('should respond on size api', async () => {
+ it('should respond on middleware api', async () => {
const data = await next
- .fetch('/api/size')
+ .fetch('/middleware')
.then((res) => res.ok && res.json())
- expect(data).toEqual({ size: 30079 })
+ expect(data).toEqual({
+ imported: expect.objectContaining({
+ src: expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ }),
+ url: expect.stringMatching(/blob:vercel\.[0-9a-f]{8,}\.png$/),
+ })
})
- it('should respond on basename api', async () => {
+ it('should respond on webmanifest', async () => {
const data = await next
- .fetch('/api/basename')
+ .fetch('/manifest.webmanifest')
.then((res) => res.ok && res.json())
expect(data).toEqual({
- basename: expect.stringMatching(/^vercel\.[0-9a-f]{8}\.png$/),
+ short_name: 'Next.js',
+ name: 'Next.js',
+ icons: [
+ {
+ src: expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ type: 'image/png',
+ sizes: '512x512',
+ },
+ ],
+ })
+ })
+
+ const expectedPage =
+ /Hello \/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png/
+
+ describe('app router', () => {
+ for (const page of ['/rsc', '/client']) {
+ it(`should render the ${page} page`, async () => {
+ const $ = await next.render$(page)
+ expect($('main').text()).toMatch(expectedPage)
+ })
+
+ it(`should client-render the ${page} page`, async () => {
+ const browser = await next.browser(page)
+ await retry(async () =>
+ expect(await browser.elementByCss('main').text()).toMatch(
+ expectedPage
+ )
+ )
+ })
+ }
+
+ it('should respond on API', async () => {
+ const data = await next.fetch('/api').then((res) => res.ok && res.json())
+
+ expect(data).toEqual({
+ imported: expect.objectContaining({
+ src: expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ }),
+ url: expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ })
+ })
+ })
+
+ describe('pages router', () => {
+ for (const page of ['/pages/static', '/pages/ssr', '/pages/ssg']) {
+ it(`should render the ${page} page`, async () => {
+ const $ = await next.render$(page)
+ expect($('main').text()).toMatch(expectedPage)
+ })
+
+ it(`should client-render the ${page} page`, async () => {
+ const browser = await next.browser(page)
+ await retry(async () =>
+ expect(await browser.elementByCss('main').text()).toMatch(
+ expectedPage
+ )
+ )
+ })
+ }
+
+ it('should respond on size api', async () => {
+ const data = await next
+ .fetch('/api/pages/size')
+ .then((res) => res.ok && res.json())
+
+ expect(data).toEqual({ size: 30079 })
+ })
+
+ it('should respond on basename api', async () => {
+ const data = await next
+ .fetch('/api/pages/basename')
+ .then((res) => res.ok && res.json())
+
+ expect(data).toEqual({
+ basename: expect.stringMatching(/^vercel\.[0-9a-f]{8}\.png$/),
+ })
})
})
})
From a7a09b617cddef1dc18fe270b319e7c0909a3248 Mon Sep 17 00:00:00 2001
From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Date: Wed, 8 Oct 2025 12:26:25 +0200
Subject: [PATCH 02/10] f test
---
test/e2e/url/app/client/page.js | 5 +-
test/e2e/url/app/manifest.js | 2 +
test/e2e/url/app/rsc/page.js | 5 +-
test/e2e/url/middleware.ts | 4 +-
test/e2e/url/pages/api/pages/basename.js | 7 --
test/e2e/url/pages/api/pages/index.js | 12 ++++
test/e2e/url/pages/api/pages/size.js | 7 --
test/e2e/url/pages/pages/ssg.js | 7 +-
test/e2e/url/pages/pages/ssr.js | 7 +-
test/e2e/url/pages/pages/static.js | 5 +-
test/e2e/url/url.test.ts | 85 ++++++++++++++----------
11 files changed, 84 insertions(+), 62 deletions(-)
delete mode 100644 test/e2e/url/pages/api/pages/basename.js
create mode 100644 test/e2e/url/pages/api/pages/index.js
delete mode 100644 test/e2e/url/pages/api/pages/size.js
diff --git a/test/e2e/url/app/client/page.js b/test/e2e/url/app/client/page.js
index e1fddf79c865bc..810acb958590dd 100644
--- a/test/e2e/url/app/client/page.js
+++ b/test/e2e/url/app/client/page.js
@@ -1,11 +1,12 @@
'use client'
-const url = new URL('../../public/vercel.png', import.meta.url).pathname
+import imported from '../../public/vercel.png'
+const url = new URL('../../public/vercel.png', import.meta.url).toString()
export default function Index(props) {
return (
- Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+ Hello {imported.src}+{url}
)
}
diff --git a/test/e2e/url/app/manifest.js b/test/e2e/url/app/manifest.js
index 544ecf4c6fbc63..b19203108ff7d9 100644
--- a/test/e2e/url/app/manifest.js
+++ b/test/e2e/url/app/manifest.js
@@ -1,4 +1,5 @@
import icon from '../public/vercel.png'
+const url = new URL('../public/vercel.png', import.meta.url).toString()
export default function manifest() {
return {
@@ -11,5 +12,6 @@ export default function manifest() {
sizes: '512x512',
},
],
+ description: url,
}
}
diff --git a/test/e2e/url/app/rsc/page.js b/test/e2e/url/app/rsc/page.js
index 3db56282512a5b..ce35c94a1ec36d 100644
--- a/test/e2e/url/app/rsc/page.js
+++ b/test/e2e/url/app/rsc/page.js
@@ -1,9 +1,10 @@
-const url = new URL('../../public/vercel.png', import.meta.url).pathname
+import imported from '../../public/vercel.png'
+const url = new URL('../../public/vercel.png', import.meta.url).toString()
export default function Index(props) {
return (
- Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+ Hello {imported.src}+{url}
)
}
diff --git a/test/e2e/url/middleware.ts b/test/e2e/url/middleware.ts
index bf4ab3bcaa383e..1d87d3d5bb57c1 100644
--- a/test/e2e/url/middleware.ts
+++ b/test/e2e/url/middleware.ts
@@ -2,10 +2,10 @@ import { NextRequest, NextResponse } from 'next/server'
// @ts-ignore
import imported from './public/vercel.png'
-const url = new URL('./public/vercel.png', import.meta.url)
+const url = new URL('./public/vercel.png', import.meta.url).toString()
export async function middleware(req: NextRequest) {
- if (req.nextUrl.pathname === '/middleware') {
+ if (req.nextUrl.toString().endsWith('/middleware')) {
return Response.json({ imported, url })
}
diff --git a/test/e2e/url/pages/api/pages/basename.js b/test/e2e/url/pages/api/pages/basename.js
deleted file mode 100644
index 22104403c5bcaf..00000000000000
--- a/test/e2e/url/pages/api/pages/basename.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import path from 'path'
-
-const img = new URL('../../../public/vercel.png', import.meta.url)
-
-export default (req, res) => {
- res.json({ basename: path.posix.basename(img.pathname) })
-}
diff --git a/test/e2e/url/pages/api/pages/index.js b/test/e2e/url/pages/api/pages/index.js
new file mode 100644
index 00000000000000..17347a6eaa50d1
--- /dev/null
+++ b/test/e2e/url/pages/api/pages/index.js
@@ -0,0 +1,12 @@
+import fs from 'fs'
+
+import imported from '../../../public/vercel.png'
+const url = new URL('../../../public/vercel.png', import.meta.url)
+
+export default (req, res) => {
+ res.json({
+ imported,
+ url: url.toString(),
+ size: fs.readFileSync(url).length,
+ })
+}
diff --git a/test/e2e/url/pages/api/pages/size.js b/test/e2e/url/pages/api/pages/size.js
deleted file mode 100644
index 2e961a4dcd5a43..00000000000000
--- a/test/e2e/url/pages/api/pages/size.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import fs from 'fs'
-
-const img = new URL('../../../public/vercel.png', import.meta.url)
-
-export default (req, res) => {
- res.json({ size: fs.readFileSync(img).length })
-}
diff --git a/test/e2e/url/pages/pages/ssg.js b/test/e2e/url/pages/pages/ssg.js
index d6a4221eb23abf..fe8d852cca225a 100644
--- a/test/e2e/url/pages/pages/ssg.js
+++ b/test/e2e/url/pages/pages/ssg.js
@@ -1,7 +1,9 @@
+import imported from '../../public/vercel.png'
+
export async function getStaticProps() {
return {
props: {
- url: new URL('../../public/vercel.png', import.meta.url).pathname,
+ url: new URL('../../public/vercel.png', import.meta.url).toString(),
},
}
}
@@ -9,7 +11,8 @@ export async function getStaticProps() {
export default function Index({ url }) {
return (
- Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+ Hello {imported.src}+
+ {new URL('../../public/vercel.png', import.meta.url).toString()}+{url}
)
}
diff --git a/test/e2e/url/pages/pages/ssr.js b/test/e2e/url/pages/pages/ssr.js
index d2ce01363cec01..ca2572a4b85157 100644
--- a/test/e2e/url/pages/pages/ssr.js
+++ b/test/e2e/url/pages/pages/ssr.js
@@ -1,7 +1,9 @@
+import imported from '../../public/vercel.png'
+
export function getServerSideProps() {
return {
props: {
- url: new URL('../../public/vercel.png', import.meta.url).pathname,
+ url: new URL('../../public/vercel.png', import.meta.url).toString(),
},
}
}
@@ -9,7 +11,8 @@ export function getServerSideProps() {
export default function Index({ url }) {
return (
- Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+ Hello {imported.src}+
+ {new URL('../../public/vercel.png', import.meta.url).toString()}+{url}
)
}
diff --git a/test/e2e/url/pages/pages/static.js b/test/e2e/url/pages/pages/static.js
index 3db56282512a5b..ce35c94a1ec36d 100644
--- a/test/e2e/url/pages/pages/static.js
+++ b/test/e2e/url/pages/pages/static.js
@@ -1,9 +1,10 @@
-const url = new URL('../../public/vercel.png', import.meta.url).pathname
+import imported from '../../public/vercel.png'
+const url = new URL('../../public/vercel.png', import.meta.url).toString()
export default function Index(props) {
return (
- Hello {new URL('../../public/vercel.png', import.meta.url).pathname}+{url}
+ Hello {imported.src}+{url}
)
}
diff --git a/test/e2e/url/url.test.ts b/test/e2e/url/url.test.ts
index cfa397bed816db..eb5cd5726bfcff 100644
--- a/test/e2e/url/url.test.ts
+++ b/test/e2e/url/url.test.ts
@@ -1,6 +1,11 @@
import { retry } from 'next-test-utils'
import { nextTestSetup } from 'e2e-utils'
+// | | Pages Client | Pages Server (SSR,RSC) | API Routes/Middleware | Metadata Routes |
+// |---------|-------------------------|-------------------------|-------------------------|-------------------------|
+// | new URL | /_next/static/media/... | /_next/static/media/... | /server/assets/... | /_next/static/media/... |
+// | import | /_next/static/media/... | /_next/static/media/... | /_next/static/media/... | /_next/static/media/... |
+// |---------|-------------------------|-------------------------|-------------------------|-------------------------|
describe(`Handle new URL asset references`, () => {
const { next } = nextTestSetup({
files: __dirname,
@@ -17,34 +22,37 @@ describe(`Handle new URL asset references`, () => {
/^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
),
}),
- url: expect.stringMatching(/blob:vercel\.[0-9a-f]{8,}\.png$/),
- })
- })
-
- it('should respond on webmanifest', async () => {
- const data = await next
- .fetch('/manifest.webmanifest')
- .then((res) => res.ok && res.json())
-
- expect(data).toEqual({
- short_name: 'Next.js',
- name: 'Next.js',
- icons: [
- {
- src: expect.stringMatching(
- /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
- ),
- type: 'image/png',
- sizes: '512x512',
- },
- ],
+ url: expect.stringMatching(/^blob:.*vercel\.[0-9a-f]{8,}\.png$/),
})
})
const expectedPage =
- /Hello \/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png/
+ /^Hello \/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png(\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png(\+\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png)?)?$/
describe('app router', () => {
+ it('should respond on webmanifest', async () => {
+ const data = await next
+ .fetch('/manifest.webmanifest')
+ .then((res) => res.ok && res.json())
+
+ expect(data).toEqual({
+ short_name: 'Next.js',
+ name: 'Next.js',
+ icons: [
+ {
+ src: expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ type: 'image/png',
+ sizes: '512x512',
+ },
+ ],
+ description: expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ })
+ })
+
for (const page of ['/rsc', '/client']) {
it(`should render the ${page} page`, async () => {
const $ = await next.render$(page)
@@ -70,9 +78,14 @@ describe(`Handle new URL asset references`, () => {
/^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
),
}),
- url: expect.stringMatching(
- /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
- ),
+ // TODO Webpack bug?
+ url: process.env.IS_TURBOPACK_TEST
+ ? expect.stringMatching(
+ /file:.*\/.next\/server\/.*\/vercel\.[0-9a-f]{8}\.png$/
+ )
+ : expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
})
})
})
@@ -94,21 +107,21 @@ describe(`Handle new URL asset references`, () => {
})
}
- it('should respond on size api', async () => {
- const data = await next
- .fetch('/api/pages/size')
- .then((res) => res.ok && res.json())
-
- expect(data).toEqual({ size: 30079 })
- })
-
- it('should respond on basename api', async () => {
+ it('should respond on API', async () => {
const data = await next
- .fetch('/api/pages/basename')
+ .fetch('/api/pages/')
.then((res) => res.ok && res.json())
expect(data).toEqual({
- basename: expect.stringMatching(/^vercel\.[0-9a-f]{8}\.png$/),
+ imported: expect.objectContaining({
+ src: expect.stringMatching(
+ /^\/_next\/static\/media\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ }),
+ url: expect.stringMatching(
+ /file:.*\/.next\/server\/.*\/vercel\.[0-9a-f]{8}\.png$/
+ ),
+ size: 30079,
})
})
})
From 8bd09d3da2a4acdafed1a1ea49c15169243b7202 Mon Sep 17 00:00:00 2001
From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Date: Thu, 9 Oct 2025 16:13:48 +0200
Subject: [PATCH 03/10] wip
---
crates/next-api/src/project.rs | 14 ++++-
crates/next-core/src/next_edge/context.rs | 9 ++-
crates/next-core/src/next_image/module.rs | 4 +-
crates/next-core/src/next_server/context.rs | 5 ++
.../turbopack-browser/src/chunking_context.rs | 63 ++++++++++++++++---
.../src/chunk/chunking_context.rs | 3 +-
.../turbopack-nodejs/src/chunking_context.rs | 59 +++++++++++++++--
turbopack/crates/turbopack-static/src/css.rs | 9 +--
turbopack/crates/turbopack-static/src/ecma.rs | 22 ++++---
.../turbopack-static/src/output_asset.rs | 12 +++-
turbopack/crates/turbopack/src/lib.rs | 11 ++--
.../turbopack/src/module_options/mod.rs | 16 ++++-
.../src/module_options/module_rule.rs | 5 +-
13 files changed, 189 insertions(+), 43 deletions(-)
diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs
index 1f142320e8e591..d2571c9a94af99 100644
--- a/crates/next-api/src/project.rs
+++ b/crates/next-api/src/project.rs
@@ -1089,7 +1089,11 @@ impl Project {
self.next_config().computed_asset_prefix().owned().await?,
)
} else {
- get_server_chunking_context(options)
+ get_server_chunking_context(
+ options,
+ self.client_relative_path().owned().await?,
+ self.next_config().computed_asset_prefix().owned().await?,
+ )
})
}
@@ -1115,10 +1119,14 @@ impl Project {
get_edge_chunking_context_with_client_assets(
options,
self.client_relative_path().owned().await?,
- self.next_config().computed_asset_prefix(),
+ self.next_config().computed_asset_prefix().owned().await?,
)
} else {
- get_edge_chunking_context(options)
+ get_edge_chunking_context(
+ options,
+ self.client_relative_path().owned().await?,
+ self.next_config().computed_asset_prefix().owned().await?,
+ )
})
}
diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs
index cd780efb06015e..091d734f40ccac 100644
--- a/crates/next-core/src/next_edge/context.rs
+++ b/crates/next-core/src/next_edge/context.rs
@@ -210,7 +210,7 @@ pub struct EdgeChunkingContextOptions {
pub async fn get_edge_chunking_context_with_client_assets(
options: EdgeChunkingContextOptions,
client_root: FileSystemPath,
- asset_prefix: ResolvedVc