Skip to content

Commit f2cf092

Browse files
authored
Print error when images.loader is assigned but images.path is not (#30080)
Fixes #29744
1 parent 6f3dc01 commit f2cf092

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

docs/api-reference/next/image.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Must be one of the following:
3737

3838
1. A [statically imported](/docs/basic-features/image-optimization.md#local-images) image file, or
3939
2. A path string. This can be either an absolute external URL,
40-
or an internal path depending on the [loader](#loader).
40+
or an internal path depending on the [loader](#loader) prop or [loader configuration](#loader-configuration).
4141

4242
When using an external URL, you must add it to
4343
[domains](#domains) in
@@ -250,7 +250,7 @@ module.exports = {
250250

251251
### Loader Configuration
252252

253-
If you want to use a cloud provider to optimize images instead of using the Next.js built-in Image Optimization API, you can configure the `loader` and `path` prefix in your `next.config.js` file. This allows you to use relative URLs for the Image `src` and automatically generate the correct absolute URL for your provider.
253+
If you want to use a cloud provider to optimize images instead of using the Next.js built-in Image Optimization API, you can configure the `loader` and `path` prefix in your `next.config.js` file. This allows you to use relative URLs for the Image [`src`](#src) and automatically generate the correct absolute URL for your provider.
254254

255255
```js
256256
module.exports = {

packages/next/server/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,16 @@ function assignDefaults(userConfig: { [key: string]: any }) {
288288
)
289289
}
290290

291+
if (
292+
images.loader !== 'default' &&
293+
images.loader !== 'custom' &&
294+
!(images.path || '').startsWith('http')
295+
) {
296+
throw new Error(
297+
`Specified images.loader property (${images.loader}) also requires images.path property to be assigned to a URL prefix.\nSee more info here: https://nextjs.org/docs/api-reference/next/image#loader-configuration`
298+
)
299+
}
300+
291301
// Append trailing slash for non-default loaders and when trailingSlash is set
292302
if (images.path) {
293303
if (

test/integration/image-optimizer/test/index.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,31 @@ describe('Image Optimizer', () => {
945945
`Specified images.formats should be an Array of mime type strings, received invalid values (jpeg)`
946946
)
947947
})
948+
949+
it('should error when images.loader is assigned but images.path is not', async () => {
950+
await nextConfig.replace(
951+
'{ /* replaceme */ }',
952+
JSON.stringify({
953+
images: {
954+
loader: 'imgix',
955+
},
956+
})
957+
)
958+
let stderr = ''
959+
960+
app = await launchApp(appDir, await findPort(), {
961+
onStderr(msg) {
962+
stderr += msg || ''
963+
},
964+
})
965+
await waitFor(1000)
966+
await killApp(app).catch(() => {})
967+
await nextConfig.restore()
968+
969+
expect(stderr).toContain(
970+
`Specified images.loader property (imgix) also requires images.path property to be assigned to a URL prefix.`
971+
)
972+
})
948973
})
949974

950975
// domains for testing

0 commit comments

Comments
 (0)