mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
Since the [image configuration options](https://nextjs.org/docs/app/api-reference/components/image#configuration-options) have all the necessary options for `images` that need to be addressed in the [next.config.js options](https://nextjs.org/docs/app/api-reference/next-config-js/images), we refer to them without making significant changes. Also, `use client` is required to use the `loader` option in the App Router but not Pages. Closes #62793 --------- Co-authored-by: Steven <[email protected]>
228 lines
7.3 KiB
Plaintext
228 lines
7.3 KiB
Plaintext
---
|
|
title: images
|
|
description: Custom configuration for the next/image loader
|
|
---
|
|
|
|
{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
|
|
|
|
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 `next.config.js` with the following:
|
|
|
|
```js filename="next.config.js"
|
|
module.exports = {
|
|
images: {
|
|
loader: 'custom',
|
|
loaderFile: './my/image/loader.js',
|
|
},
|
|
}
|
|
```
|
|
|
|
This `loaderFile` must point to a file relative to the root of your Next.js application. The file must export a default function that returns a string, for example:
|
|
|
|
<AppOnly>
|
|
|
|
```js filename="my/image/loader.js"
|
|
'use client'
|
|
|
|
export default function myImageLoader({ src, width, quality }) {
|
|
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
|
|
}
|
|
```
|
|
|
|
Alternatively, you can use the [`loader` prop](/docs/app/api-reference/components/image#loader) to pass the function to each instance of `next/image`.
|
|
|
|
> **Good to know**: Customizing the image loader file, which accepts a function, requires using [Client Components](/docs/app/building-your-application/rendering/client-components) to serialize the provided function.
|
|
|
|
To learn more about configuring the behavior of the built-in [Image Optimization API](/docs/app/building-your-application/optimizing/images) and the [Image Component](/docs/app/api-reference/components/image), see [Image Configuration Options](/docs/app/api-reference/components/image#configuration-options) for available options.
|
|
|
|
</AppOnly>
|
|
|
|
<PagesOnly>
|
|
|
|
```js filename="my/image/loader.js"
|
|
export default function myImageLoader({ src, width, quality }) {
|
|
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
|
|
}
|
|
```
|
|
|
|
Alternatively, you can use the [`loader` prop](/docs/pages/api-reference/components/image#loader) to pass the function to each instance of `next/image`.
|
|
|
|
To learn more about configuring the behavior of the built-in [Image Optimization API](/docs/pages/building-your-application/optimizing/images) and the [Image Component](/docs/pages/api-reference/components/image), see [Image Configuration Options](/docs/pages/api-reference/components/image#configuration-options) for available options.
|
|
|
|
</PagesOnly>
|
|
|
|
## Example Loader Configuration
|
|
|
|
- [Akamai](#akamai)
|
|
- [AWS CloudFront](#aws-cloudfront)
|
|
- [Cloudinary](#cloudinary)
|
|
- [Cloudflare](#cloudflare)
|
|
- [Contentful](#contentful)
|
|
- [Fastly](#fastly)
|
|
- [Gumlet](#gumlet)
|
|
- [ImageEngine](#imageengine)
|
|
- [Imgix](#imgix)
|
|
- [Thumbor](#thumbor)
|
|
- [Sanity](#sanity)
|
|
- [Sirv](#sirv)
|
|
- [Supabase](#supabase)
|
|
|
|
### Akamai
|
|
|
|
```js
|
|
// Docs: https://techdocs.akamai.com/ivm/reference/test-images-on-demand
|
|
export default function akamaiLoader({ src, width, quality }) {
|
|
return `https://example.com/${src}?imwidth=${width}`
|
|
}
|
|
```
|
|
|
|
### AWS CloudFront
|
|
|
|
```js
|
|
// Docs: https://aws.amazon.com/developer/application-security-performance/articles/image-optimization
|
|
export default function cloudfrontLoader({ src, width, quality }) {
|
|
const url = new URL(`https://example.com${src}`)
|
|
url.searchParams.set('format', 'auto')
|
|
url.searchParams.set('width', width.toString())
|
|
url.searchParams.set('quality', (quality || 75).toString())
|
|
return url.href
|
|
```
|
|
|
|
### Cloudinary
|
|
|
|
```js
|
|
// Demo: https://res.cloudinary.com/demo/image/upload/w_300,c_limit,q_auto/turtles.jpg
|
|
export default function cloudinaryLoader({ src, width, quality }) {
|
|
const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
|
|
return `https://example.com/${params.join(',')}${src}`
|
|
}
|
|
```
|
|
|
|
### Cloudflare
|
|
|
|
```js
|
|
// Docs: https://developers.cloudflare.com/images/url-format
|
|
export default function cloudflareLoader({ src, width, quality }) {
|
|
const params = [`width=${width}`, `quality=${quality || 75}`, 'format=auto']
|
|
return `https://example.com/cdn-cgi/image/${params.join(',')}/${src}`
|
|
}
|
|
```
|
|
|
|
### Contentful
|
|
|
|
```js
|
|
// Docs: https://www.contentful.com/developers/docs/references/images-api/
|
|
export default function contentfulLoader({ src, width, quality }) {
|
|
const url = new URL(`https://example.com${src}`)
|
|
url.searchParams.set('fm', 'webp')
|
|
url.searchParams.set('w', width.toString())
|
|
url.searchParams.set('q', (quality || 75).toString())
|
|
return url.href
|
|
}
|
|
```
|
|
|
|
### Fastly
|
|
|
|
```js
|
|
// Docs: https://developer.fastly.com/reference/io/
|
|
export default function fastlyLoader({ src, width, quality }) {
|
|
const url = new URL(`https://example.com${src}`)
|
|
url.searchParams.set('auto', 'webp')
|
|
url.searchParams.set('width', width.toString())
|
|
url.searchParams.set('quality', (quality || 75).toString())
|
|
return url.href
|
|
}
|
|
```
|
|
|
|
### Gumlet
|
|
|
|
```js
|
|
// Docs: https://docs.gumlet.com/reference/image-transform-size
|
|
export default function gumletLoader({ src, width, quality }) {
|
|
const url = new URL(`https://example.com${src}`)
|
|
url.searchParams.set('format', 'auto')
|
|
url.searchParams.set('w', width.toString())
|
|
url.searchParams.set('q', (quality || 75).toString())
|
|
return url.href
|
|
}
|
|
```
|
|
|
|
### ImageEngine
|
|
|
|
```js
|
|
// Docs: https://support.imageengine.io/hc/en-us/articles/360058880672-Directives
|
|
export default function imageengineLoader({ src, width, quality }) {
|
|
const compression = 100 - (quality || 50)
|
|
const params = [`w_${width}`, `cmpr_${compression}`)]
|
|
return `https://example.com${src}?imgeng=/${params.join('/')`
|
|
}
|
|
```
|
|
|
|
### Imgix
|
|
|
|
```js
|
|
// Demo: https://static.imgix.net/daisy.png?format=auto&fit=max&w=300
|
|
export default function imgixLoader({ src, width, quality }) {
|
|
const url = new URL(`https://example.com${src}`)
|
|
const params = url.searchParams
|
|
params.set('auto', params.getAll('auto').join(',') || 'format')
|
|
params.set('fit', params.get('fit') || 'max')
|
|
params.set('w', params.get('w') || width.toString())
|
|
params.set('q', (quality || 50).toString())
|
|
return url.href
|
|
}
|
|
```
|
|
|
|
### Thumbor
|
|
|
|
```js
|
|
// Docs: https://thumbor.readthedocs.io/en/latest/
|
|
export default function thumborLoader({ src, width, quality }) {
|
|
const params = [`${width}x0`, `filters:quality(${quality || 75})`]
|
|
return `https://example.com${params.join('/')}${src}`
|
|
}
|
|
```
|
|
|
|
### Sanity
|
|
|
|
```js
|
|
// Docs: https://www.sanity.io/docs/image-urls
|
|
export default function sanityLoader({ src, width, quality }) {
|
|
const prj = 'zp7mbokg'
|
|
const dataset = 'production'
|
|
const url = new URL(`https://cdn.sanity.io/images/${prj}/${dataset}${src}`)
|
|
url.searchParams.set('auto', 'format')
|
|
url.searchParams.set('fit', 'max')
|
|
url.searchParams.set('w', width.toString())
|
|
if (quality) {
|
|
url.searchParams.set('q', quality.toString())
|
|
}
|
|
return url.href
|
|
}
|
|
```
|
|
|
|
### Sirv
|
|
|
|
```js
|
|
// Docs: https://sirv.com/help/articles/dynamic-imaging/
|
|
export default function sirvLoader({ src, width, quality }) {
|
|
const url = new URL(`https://example.com${src}`)
|
|
const params = url.searchParams
|
|
params.set('format', params.getAll('format').join(',') || 'optimal')
|
|
params.set('w', params.get('w') || width.toString())
|
|
params.set('q', (quality || 85).toString())
|
|
return url.href
|
|
}
|
|
```
|
|
|
|
### Supabase
|
|
|
|
```js
|
|
// Docs: https://supabase.com/docs/guides/storage/image-transformations#nextjs-loader
|
|
export default function supabaseLoader({ src, width, quality }) {
|
|
const url = new URL(`https://example.com${src}`)
|
|
url.searchParams.set('width', width.toString())
|
|
url.searchParams.set('quality', (quality || 75).toString())
|
|
return url.href
|
|
}
|
|
```
|