Skip to content

Commit

Permalink
Fix next/image when src is webp but browser doesnt support it (#35190)
Browse files Browse the repository at this point in the history
* Fix `next/image` when src is webp but browser doesnt support it

* Exclude old sharp since it doesnt support AVIF
  • Loading branch information
styfle committed Mar 10, 2022
1 parent 8472069 commit 0355e5f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
7 changes: 6 additions & 1 deletion packages/next/server/image-optimizer.ts
Expand Up @@ -419,7 +419,12 @@ export async function imageOptimizer(

if (mimeType) {
contentType = mimeType
} else if (upstreamType?.startsWith('image/') && getExtension(upstreamType)) {
} else if (
upstreamType?.startsWith('image/') &&
getExtension(upstreamType) &&
upstreamType !== WEBP &&
upstreamType !== AVIF
) {
contentType = upstreamType
} else {
contentType = JPEG
Expand Down
Binary file not shown.
Binary file added test/integration/image-optimizer/app/public/test.webp
Binary file not shown.
38 changes: 38 additions & 0 deletions test/integration/image-optimizer/test/util.js
Expand Up @@ -313,6 +313,44 @@ export function runTests(ctx) {
)
})

it('should downlevel webp format to jpeg for old Safari', async () => {
const accept =
'image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5'
const query = { w: ctx.w, q: 74, url: '/test.webp' }
const opts = { headers: { accept } }
const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, opts)
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toContain('image/jpeg')
expect(res.headers.get('Cache-Control')).toBe(
`public, max-age=0, must-revalidate`
)
expect(res.headers.get('Vary')).toBe('Accept')
expect(res.headers.get('etag')).toBeTruthy()
expect(res.headers.get('Content-Disposition')).toBe(
`inline; filename="test.jpeg"`
)
})

if (!ctx.isOutdatedSharp) {
it('should downlevel avif format to jpeg for old Safari', async () => {
const accept =
'image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5'
const query = { w: ctx.w, q: 74, url: '/test.avif' }
const opts = { headers: { accept } }
const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, opts)
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toContain('image/jpeg')
expect(res.headers.get('Cache-Control')).toBe(
`public, max-age=0, must-revalidate`
)
expect(res.headers.get('Vary')).toBe('Accept')
expect(res.headers.get('etag')).toBeTruthy()
expect(res.headers.get('Content-Disposition')).toBe(
`inline; filename="test.jpeg"`
)
})
}

it('should fail when url is missing', async () => {
const query = { w: ctx.w, q: 100 }
const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, {})
Expand Down

0 comments on commit 0355e5f

Please sign in to comment.