Skip to content

[backport v14]: fix(next/image): improve and simplify detect-content-type (#82118) #82179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 30, 2025

Conversation

ztanner
Copy link
Member

@ztanner ztanner commented Jul 29, 2025

Add support for detecting more src image formats via magic number. The
src image formats are handled as follows:

- `image/jxl` - serve as is (since safari can render it)
- `image/heic` - serve as is (since safari can render it)
- `image/jp2` - serve as is (since safari can render it)
- `application/pdf` - error (since no browser will render it)
- `image/pic` - error (since no browser will render it)

We also fallback to `sharp().metadata()` if we can't detect the magic
number to ensure correctness.
Copy link

vercel bot commented Jul 29, 2025

Notifying the following users due to files changed in this PR based on this repo's notify modifiers:

@timneutkens, @ijjk, @shuding, @huozhi:

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

@ijjk
Copy link
Member

ijjk commented Jul 29, 2025

Failing test suites

Commit: 3f00274

pnpm test-start test/e2e/app-dir/turbopack-reports/turbopack-reports.test.ts

  • turbopack-reports > should render page importing sqlite3
Expand output

● turbopack-reports › should render page importing sqlite3

next build failed with code/signal 1

  90 |           if (code || signal)
  91 |             reject(
> 92 |               new Error(`next build failed with code/signal ${code || signal}`)
     |               ^
  93 |             )
  94 |           else resolve()
  95 |         })

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:92:15)

Read more about building and testing Next.js in contributing.md.

pnpm test-start test/e2e/prerender-native-module.test.ts

  • prerender native module > should render index correctly
  • prerender native module > should render /blog/first correctly
  • prerender native module > should render /blog/second correctly
  • prerender native module > should output traces
Expand output

● prerender native module › should render index correctly

next build failed with code/signal 1

  90 |           if (code || signal)
  91 |             reject(
> 92 |               new Error(`next build failed with code/signal ${code || signal}`)
     |               ^
  93 |             )
  94 |           else resolve()
  95 |         })

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:92:15)

● prerender native module › should render /blog/first correctly

next build failed with code/signal 1

  90 |           if (code || signal)
  91 |             reject(
> 92 |               new Error(`next build failed with code/signal ${code || signal}`)
     |               ^
  93 |             )
  94 |           else resolve()
  95 |         })

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:92:15)

● prerender native module › should render /blog/second correctly

next build failed with code/signal 1

  90 |           if (code || signal)
  91 |             reject(
> 92 |               new Error(`next build failed with code/signal ${code || signal}`)
     |               ^
  93 |             )
  94 |           else resolve()
  95 |         })

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:92:15)

● prerender native module › should output traces

next build failed with code/signal 1

  90 |           if (code || signal)
  91 |             reject(
> 92 |               new Error(`next build failed with code/signal ${code || signal}`)
     |               ^
  93 |             )
  94 |           else resolve()
  95 |         })

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:92:15)

● Test suite failed to run

TypeError: Cannot read properties of undefined (reading 'destroy')

  23 |     })
  24 |   })
> 25 |   afterAll(() => next.destroy())
     |                       ^
  26 |
  27 |   it('should render index correctly', async () => {
  28 |     const browser = await webdriver(next.url, '/')

  at Object.destroy (e2e/prerender-native-module.test.ts:25:23)

Read more about building and testing Next.js in contributing.md.

@ijjk
Copy link
Member

ijjk commented Jul 29, 2025

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
buildDuration 16.9s 15.3s N/A
buildDurationCached 8.4s 7.1s N/A
nodeModulesSize 201 MB 201 MB ⚠️ +13.2 kB
nextStartRea..uration (ms) 382ms 394ms N/A
Client Bundles (main, webpack)
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
1a9f679d-HASH.js gzip 53.7 kB 53.7 kB
5428.HASH.js gzip 181 B 180 B N/A
6067-HASH.js gzip 5.14 kB 5.14 kB
6428-HASH.js gzip 31.6 kB 31.6 kB N/A
framework-HASH.js gzip 44.9 kB 44.9 kB
main-app-HASH.js gzip 242 B 243 B N/A
main-HASH.js gzip 34.2 kB 34.2 kB N/A
webpack-HASH.js gzip 1.68 kB 1.68 kB N/A
Overall change 104 kB 104 kB
Legacy Client Bundles (polyfills)
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Overall change 39.4 kB 39.4 kB
Client Pages
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
_app-HASH.js gzip 196 B 196 B
_error-HASH.js gzip 184 B 185 B N/A
amp-HASH.js gzip 502 B 504 B N/A
css-HASH.js gzip 321 B 324 B N/A
dynamic-HASH.js gzip 1.82 kB 1.82 kB N/A
edge-ssr-HASH.js gzip 258 B 257 B N/A
head-HASH.js gzip 352 B 352 B
hooks-HASH.js gzip 371 B 372 B N/A
image-HASH.js gzip 4.32 kB 4.32 kB N/A
index-HASH.js gzip 259 B 257 B N/A
link-HASH.js gzip 2.67 kB 2.68 kB N/A
routerDirect..HASH.js gzip 316 B 314 B N/A
script-HASH.js gzip 385 B 386 B N/A
withRouter-HASH.js gzip 311 B 310 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 654 B 654 B
Client Build Manifests
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
_buildManifest.js gzip 484 B 481 B N/A
Overall change 0 B 0 B
Rendered Page Sizes
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
index.html gzip 528 B 528 B
link.html gzip 542 B 539 B N/A
withRouter.html gzip 525 B 524 B N/A
Overall change 528 B 528 B
Edge SSR bundle Size
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
edge-ssr.js gzip 95.7 kB 95.7 kB N/A
page.js gzip 3.06 kB 3.06 kB N/A
Overall change 0 B 0 B
Middleware size
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
middleware-b..fest.js gzip 658 B 657 B N/A
middleware-r..fest.js gzip 156 B 154 B N/A
middleware.js gzip 25.6 kB 25.6 kB
edge-runtime..pack.js gzip 839 B 839 B
Overall change 26.4 kB 26.4 kB
Next Runtimes
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
app-page-exp...dev.js gzip 172 kB 172 kB
app-page-exp..prod.js gzip 98.4 kB 98.4 kB
app-page-tur..prod.js gzip 100 kB 100 kB
app-page-tur..prod.js gzip 94.4 kB 94.4 kB
app-page.run...dev.js gzip 146 kB 146 kB
app-page.run..prod.js gzip 92.9 kB 92.9 kB
app-route-ex...dev.js gzip 22.6 kB 22.6 kB
app-route-ex..prod.js gzip 16 kB 16 kB
app-route-tu..prod.js gzip 16 kB 16 kB
app-route-tu..prod.js gzip 15.7 kB 15.7 kB
app-route.ru...dev.js gzip 22.2 kB 22.2 kB
app-route.ru..prod.js gzip 15.7 kB 15.7 kB
pages-api-tu..prod.js gzip 9.58 kB 9.58 kB
pages-api.ru...dev.js gzip 9.85 kB 9.85 kB
pages-api.ru..prod.js gzip 9.57 kB 9.57 kB
pages-turbo...prod.js gzip 22.5 kB 22.5 kB
pages.runtim...dev.js gzip 23.2 kB 23.2 kB
pages.runtim..prod.js gzip 22.5 kB 22.5 kB
server.runti..prod.js gzip 51.8 kB 51.8 kB
Overall change 961 kB 961 kB
build cache Overall increase ⚠️
vercel/next.js 14-2-1 vercel/next.js ztanner/backport-82118 Change
0.pack gzip 1.65 MB 1.65 MB N/A
index.pack gzip 114 kB 114 kB ⚠️ +242 B
Overall change 114 kB 114 kB ⚠️ +242 B
Diff details
Diff for middleware.js

Diff too large to display

Diff for edge-ssr.js

Diff too large to display

Commit: 3f00274

@ztanner ztanner force-pushed the ztanner/backport-82118 branch 2 times, most recently from cce1a6e to d6057ed Compare July 30, 2025 00:08
@ztanner ztanner force-pushed the ztanner/backport-82118 branch from d6057ed to c253ab9 Compare July 30, 2025 00:12
@@ -1179,7 +1254,7 @@ export function runTests(ctx) {
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toBe('image/bmp')
expect(res.headers.get('Cache-Control')).toBe(
`public, max-age=${isDev ? 0 : minimumCacheTTL}, must-revalidate`
`public, max-age=0, must-revalidate`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I wouldn't expect this to change 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see the same for ico so must be because of the bypass.

@ztanner ztanner merged commit 5dd68a5 into 14-2-1 Jul 30, 2025
88 of 101 checks passed
@ztanner ztanner deleted the ztanner/backport-82118 branch July 30, 2025 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants