forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for custom image loaders via image component prop (vercel#20216)
This is a vercel#19325 reconfigured to support a loader passed in via a `loader` prop on the Image component, rather than using a config-based approach. The idea is that applications wanting to use a custom loader will create a wrapper element for the image component that incorporates that loader. See a simple example of this pattern in the integration tests. This solution is similar to the one prototyped by @ricokahler in vercel#20213 and described at vercel#18606 (comment) --- Closes vercel#19325 Fixes vercel#18606
- Loading branch information
Showing
5 changed files
with
205 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
test/integration/image-component/custom-resolver/next.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module.exports = { | ||
images: { | ||
deviceSizes: [480, 1024, 1600, 2000], | ||
imageSizes: [16, 32, 48, 64], | ||
path: 'https://globalresolver.com/myaccount/', | ||
loader: 'imgix', | ||
}, | ||
} |
36 changes: 36 additions & 0 deletions
36
test/integration/image-component/custom-resolver/pages/client-side.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import React from 'react' | ||
import Image from 'next/image' | ||
|
||
const myLoader = ({ src, width, quality }) => { | ||
return `https://customresolver.com/${src}?w~~${width},q~~${quality}` | ||
} | ||
|
||
const MyImage = (props) => { | ||
return <Image loader={myLoader} {...props}></Image> | ||
} | ||
|
||
const Page = () => { | ||
return ( | ||
<div> | ||
<p>Image Client Side Test</p> | ||
<MyImage | ||
id="basic-image" | ||
src="foo.jpg" | ||
loading="eager" | ||
width={300} | ||
height={400} | ||
quality={60} | ||
/> | ||
<Image | ||
id="unoptimized-image" | ||
unoptimized | ||
src="https://arbitraryurl.com/foo.jpg" | ||
loading="eager" | ||
width={300} | ||
height={400} | ||
/> | ||
</div> | ||
) | ||
} | ||
|
||
export default Page |
40 changes: 40 additions & 0 deletions
40
test/integration/image-component/custom-resolver/pages/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import React from 'react' | ||
import Image from 'next/image' | ||
import Link from 'next/link' | ||
|
||
const myLoader = ({ src, width, quality }) => { | ||
return `https://customresolver.com/${src}?w~~${width},q~~${quality}` | ||
} | ||
|
||
const MyImage = (props) => { | ||
return <Image loader={myLoader} {...props}></Image> | ||
} | ||
|
||
const Page = () => { | ||
return ( | ||
<div> | ||
<p>Image SSR Test</p> | ||
<MyImage | ||
id="basic-image" | ||
src="foo.jpg" | ||
loading="eager" | ||
width={300} | ||
height={400} | ||
quality={60} | ||
/> | ||
<Image | ||
id="unoptimized-image" | ||
unoptimized | ||
src="https://arbitraryurl.com/foo.jpg" | ||
loading="eager" | ||
width={300} | ||
height={400} | ||
/> | ||
<Link href="/client-side"> | ||
<a id="clientlink">Client Side</a> | ||
</Link> | ||
</div> | ||
) | ||
} | ||
|
||
export default Page |
60 changes: 60 additions & 0 deletions
60
test/integration/image-component/custom-resolver/test/index.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* eslint-env jest */ | ||
|
||
import { join } from 'path' | ||
import { killApp, findPort, nextStart, nextBuild } from 'next-test-utils' | ||
import webdriver from 'next-webdriver' | ||
|
||
jest.setTimeout(1000 * 30) | ||
|
||
const appDir = join(__dirname, '../') | ||
let appPort | ||
let app | ||
let browser | ||
|
||
function runTests() { | ||
it('Should use a custom resolver for image URL', async () => { | ||
expect(await browser.elementById('basic-image').getAttribute('src')).toBe( | ||
'https://customresolver.com/foo.jpg?w~~1024,q~~60' | ||
) | ||
}) | ||
it('should add a srcset based on the custom resolver', async () => { | ||
expect( | ||
await browser.elementById('basic-image').getAttribute('srcset') | ||
).toBe( | ||
'https://customresolver.com/foo.jpg?w~~480,q~~60 1x, https://customresolver.com/foo.jpg?w~~1024,q~~60 2x' | ||
) | ||
}) | ||
it('should support the unoptimized attribute', async () => { | ||
expect( | ||
await browser.elementById('unoptimized-image').getAttribute('src') | ||
).toBe('https://arbitraryurl.com/foo.jpg') | ||
}) | ||
} | ||
|
||
describe('Custom Resolver Tests', () => { | ||
beforeAll(async () => { | ||
await nextBuild(appDir) | ||
appPort = await findPort() | ||
app = await nextStart(appDir, appPort) | ||
}) | ||
afterAll(() => killApp(app)) | ||
describe('SSR Custom Loader Tests', () => { | ||
beforeAll(async () => { | ||
browser = await webdriver(appPort, '/') | ||
}) | ||
afterAll(async () => { | ||
browser = null | ||
}) | ||
runTests() | ||
}) | ||
describe('Client-side Custom Loader Tests', () => { | ||
beforeAll(async () => { | ||
browser = await webdriver(appPort, '/') | ||
await browser.waitForElementByCss('#clientlink').click() | ||
}) | ||
afterAll(async () => { | ||
browser = null | ||
}) | ||
runTests() | ||
}) | ||
}) |