콘텐츠로 이동

Components: Image

Source URL: https://nextjs.org/docs/pages/api-reference/components/image

Copy page

마지막 업데이트 2026년 2월 20일

Next.js Image 컴포넌트는 자동 이미지 최적화를 위해 HTML <img> 요소를 확장합니다.

app/page.js

import Image from 'next/image'
export default function Page() {
return (
<Image
src="/profile.png"
width={500}
height={500}
alt="Picture of the author"
/>
)
}

알아두면 좋은 점: Next.js 13 이전 버전을 사용한다면 컴포넌트 이름이 변경되기 전이므로 next/legacy/image 문서를 참고하세요.

다음 props를 사용할 수 있습니다:

PropExampleTypeStatus
srcsrc="/profile.png"StringRequired
altalt="Picture of the author"StringRequired
widthwidth={500}Integer (px)-
heightheight={500}Integer (px)-
fillfill={true}Boolean-
loaderloader={imageLoader}Function-
sizessizes="(max-width: 768px) 100vw, 33vw"String-
qualityquality={80}Integer (1-100)-
preloadpreload={true}Boolean-
placeholderplaceholder="blur"String-
stylestyle={{objectFit: "contain"}}Object-
onLoadingCompleteonLoadingComplete={img => done())}FunctionDeprecated
onLoadonLoad={event => done())}Function-
onErroronError(event => fail()}Function-
loadingloading="lazy"String-
blurDataURLblurDataURL="data:image/jpeg..."String-
unoptimizedunoptimized={true}Boolean-
overrideSrcoverrideSrc="/seo.png"String-
decodingdecoding="async"String-

이미지의 소스입니다. 다음 중 하나일 수 있습니다:

내부 경로 문자열.

<Image src="/profile.png" />

remotePatterns로 구성된 절대 외부 URL.

<Image src="https://example.com/profile.png" />

정적 import.

import profile from './profile.png'
export default function Page() {
return <Image src={profile} />
}

알아두면 좋은 점: 보안상의 이유로 기본 loader를 사용하는 Image Optimization API는 src 이미지를 가져올 때 헤더를 전달하지 않습니다. src 이미지에 인증이 필요하다면 Image Optimization을 비활성화하기 위해 unoptimized 속성 사용을 고려하세요.

alt 속성은 스크린 리더와 검색 엔진을 위한 이미지 설명이며, 이미지가 비활성화되었거나 로딩 중 오류가 발생했을 때의 대체 텍스트입니다.

페이지의 의미를 바꾸지 않고 이미지를 대체할 수 있는 텍스트를 포함해야 합니다. 이미지를 보조하기 위한 것이 아니며 이미지 위나 아래의 캡션에서 이미 제공되는 정보를 반복해서는 안 됩니다.

이미지가 순수 장식용이거나 사용자를 위한 것이 아닌 경우 alt 속성은 빈 문자열(alt="")이어야 합니다.

이미지 접근성 지침에 대해 더 알아보세요.

widthheight 속성은 픽셀 단위의 고유 이미지 크기를 나타냅니다. 이 속성은 브라우저가 이미지의 올바른 종횡비를 추론하여 로딩 중 레이아웃 이동을 방지하도록 공간을 예약하는 데 사용됩니다. 이미지의 렌더링된 크기 는 CSS로 제어되며 이 속성이 결정하지 않습니다.

<Image src="/profile.png" width={500} height={500} />

다음 경우를 제외하고는 widthheight 속성을 모두 설정해야 합니다:

  • 이미지가 정적으로 import된 경우
  • 이미지에 fill 속성이 있는 경우

높이와 너비를 알 수 없다면 fill 속성 사용을 권장합니다.

이미지가 부모 요소 크기만큼 확장되도록 하는 boolean입니다.

<Image src="/profile.png" fill={true} />

Positioning :

  • 부모 요소는 반드시 position: "relative", "fixed", "absolute" 중 하나를 지정해야 합니다.
  • 기본적으로 <img> 요소는 position: "absolute"를 사용합니다.

Object Fit :

이미지에 스타일을 적용하지 않으면 컨테이너에 맞춰 늘어납니다. objectFit을 사용하여 자르기와 스케일링을 제어할 수 있습니다.

  • "contain": 컨테이너에 맞게 축소하면서 종횡비를 유지합니다.
  • "cover": 컨테이너를 채우며 잘릴 수 있습니다.

positionobject-fit에 대해 자세히 알아보세요.

이미지 URL을 생성하는 사용자 정의 함수입니다. 함수는 다음 매개변수를 받고 이미지 URL 문자열을 반환합니다:

import Image from 'next/image'
const imageLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
export default function Page() {
return (
<Image
loader={imageLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}

대신 next.config.js에서 loaderFile 구성을 사용해 애플리케이션의 모든 next/image 인스턴스를 prop 없이 설정할 수 있습니다.

브레이크포인트별 이미지 크기를 정의합니다. 브라우저는 이를 사용하여 생성된 srcset 중 가장 적절한 크기를 선택합니다.

import Image from 'next/image'
export default function Page() {
return (
<div className="grid-element">
<Image
fill
src="/example.png"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
)
}

sizes는 다음 상황에서 사용해야 합니다:

  • 이미지가 fill prop을 사용하는 경우
  • CSS로 이미지를 반응형으로 만드는 경우

sizes가 없으면 브라우저는 이미지가 뷰포트(100vw)와 같은 너비라고 가정합니다. 이로 인해 불필요하게 큰 이미지를 다운로드할 수 있습니다.

또한 sizessrcset 생성 방식에 영향을 줍니다:

  • sizes 없음: Next.js는 고정 크기 이미지에 적합한 제한된 srcset(예: 1x, 2x)을 생성합니다.
  • sizes 있음: Next.js는 반응형 레이아웃에 최적화된 전체 srcset(예: 640w, 750w 등)을 생성합니다.

srcsetsizes에 대해 web.devmdn에서 더 알아보세요.

최적화된 이미지 품질을 설정하는 1에서 100 사이의 정수입니다. 값이 높을수록 파일 크기와 시각적 선명도가 증가합니다. 값이 낮을수록 파일 크기가 줄지만 선명도에 영향을 줄 수 있습니다.

// Default quality is 75
<Image quality={75} />

next.config.js에서 qualities를 구성했다면 값은 허용된 항목 중 하나와 일치해야 합니다.

알아두면 좋은 점: 원본 이미지 품질이 이미 낮다면 높은 quality 값을 설정해도 외관이 개선되지 않은 채 파일 크기만 증가합니다.

기본 이미지 요소에 CSS 스타일을 전달할 수 있습니다.

const imageStyle = {
borderRadius: '50%',
border: '1px solid #fff',
width: '100px',
height: 'auto',
}
export default function ProfileImage() {
return <Image src="..." style={imageStyle} />
}

알아두면 좋은 점: style prop으로 사용자 정의 너비를 설정하는 경우 이미지 종횡비를 유지하려면 height: 'auto'도 설정하세요.

이미지를 미리 로드할지 여부를 나타내는 boolean입니다.

// Default preload is false
<Image preload={false} />
  • true: <head><link>를 삽입하여 이미지를 미리 로드합니다.
  • false: 이미지를 미리 로드하지 않습니다.

사용해야 하는 경우:

  • 이미지가 Largest Contentful Paint (LCP) 요소인 경우
  • 이미지가 폴드 위, 일반적으로 히어로 이미지인 경우
  • <body>에서 나중에 발견되기 전에 <head>에서 이미지 로딩을 시작하려는 경우

사용하지 말아야 하는 경우:

  • 뷰포트에 따라 Largest Contentful Paint (LCP) 요소가 될 수 있는 이미지가 여러 개 있는 경우

  • loading 속성을 사용할 때.

    • fetchPriority 속성을 사용할 때.

대부분의 경우 preload 대신 loading="eager" 또는 fetchPriority="high"를 사용해야 합니다.

Next.js 16부터 동작을 명확히 하기 위해 priority 속성이 preload 속성으로 대체되어 사용 중단되었습니다.

이미지가 언제 로딩을 시작할지 제어합니다.

// Defaults to lazy
<Image loading="lazy" />
  • lazy: 뷰포트에서 계산된 거리 안에 들어올 때까지 이미지 로딩을 지연합니다.
  • eager: 페이지에서 위치와 관계없이 즉시 이미지를 로드합니다.

이미지를 즉시 로딩해야 할 때만 eager를 사용하세요.

loading attribute에 대해 자세히 알아보세요.

이미지가 로딩되는 동안 사용할 플레이스홀더를 지정하여 체감 로딩 성능을 개선합니다.

// defaults to empty
<Image placeholder="empty" />
  • empty: 이미지가 로딩되는 동안 플레이스홀더를 표시하지 않습니다.
  • blur: 이미지를 흐린 버전으로 플레이스홀더로 사용합니다. blurDataURL 속성과 함께 사용해야 합니다.
  • data:image/...: Data URL을 플레이스홀더로 사용합니다.

예시:

placeholder attribute에 대해 자세히 알아보세요.

이미지가 성공적으로 로드되기 전에 사용할 Data URL입니다. 자동으로 설정되거나 placeholder="blur" 속성과 함께 사용할 수 있습니다.

<Image placeholder="blur" blurDataURL="..." />

이미지는 자동으로 확대되고 블러 처리되므로 10px 이하의 아주 작은 이미지를 사용하는 것이 좋습니다.

Automatic

srcjpg, png, webp, avif 파일의 정적 import인 경우, 이미지가 애니메이션이 아니라면 blurDataURL이 자동으로 추가됩니다.

Manually set

이미지가 동적이거나 원격인 경우 blurDataURL을 직접 제공해야 합니다. 생성하려면 다음을 사용할 수 있습니다.

큰 blurDataURL은 성능을 저하시킬 수 있습니다. 작고 단순하게 유지하세요.

예시:

이미지가 완전히 로드되고 placeholder가 제거되면 호출되는 콜백 함수입니다.

<Image onLoad={(e) => console.log(e.target.naturalWidth)} />

콜백 함수는 target이 기본 <img> 요소를 참조하는 이벤트 객체 하나를 인수로 받습니다.

이미지 로드에 실패했을 때 호출되는 콜백 함수입니다.

<Image onError={(e) => console.error(e.target.id)} />

이미지를 최적화할지 여부를 나타내는 불리언입니다. 1KB 미만의 작은 이미지, SVG 같은 벡터 이미지, GIF 같은 애니메이션 이미지처럼 최적화로 이득이 없는 경우에 유용합니다.

import Image from 'next/image'
const UnoptimizedImage = (props) => {
// Default is false
return <Image {...props} unoptimized />
}
  • true: 소스 이미지는 품질, 크기, 형식을 변경하지 않고 src 그대로 제공합니다.
  • false: 소스 이미지를 최적화합니다.

Next.js 12.3.0부터는 next.config.js를 다음 설정으로 업데이트하여 모든 이미지에 이 prop을 일괄 적용할 수 있습니다:

next.config.js

module.exports = {
images: {
unoptimized: true,
},
}

<Image> 컴포넌트에 src prop을 제공하면 결과 <img>에 대한 srcsetsrc 속성이 자동으로 생성됩니다.

input.js

<Image src="/profile.jpg" />

output.html

<img
srcset="
/_next/image?url=%2Fprofile.jpg&w=640&q=75 1x,
/_next/image?url=%2Fprofile.jpg&w=828&q=75 2x
"
src="/_next/image?url=%2Fprofile.jpg&w=828&q=75"
/>

일부 경우에는 생성된 src 속성이 바람직하지 않아 overrideSrc prop으로 이를 대체하고 싶을 수 있습니다.

예를 들어 기존 웹사이트를 <img>에서 <Image>로 마이그레이션하는 동안 이미지 순위 유지나 재크롤 방지 같은 SEO 목적으로 동일한 src 속성을 유지하고 싶을 수 있습니다.

input.js

<Image src="/profile.jpg" overrideSrc="/override.jpg" />

output.html

<img
srcset="
/_next/image?url=%2Fprofile.jpg&w=640&q=75 1x,
/_next/image?url=%2Fprofile.jpg&w=828&q=75 2x
"
src="/override.jpg"
/>

이미지를 디코딩할 때 브라우저가 다른 콘텐츠 업데이트를 기다릴지 여부에 대한 힌트를 제공합니다.

// Default is async
<Image decoding="async" />
  • async: 이미지를 비동기적으로 디코딩하여 완료되기 전에 다른 콘텐츠가 렌더링될 수 있도록 합니다.
  • sync: 다른 콘텐츠와 원자적으로 표시되도록 이미지를 동기적으로 디코딩합니다.
  • auto: 선호 설정이 없습니다. 브라우저가 최적의 방식을 선택합니다.

decoding attribute에 대해 자세히 알아보세요.

<Image /> 컴포넌트의 다른 속성은 srcSet을 제외하고 기본 img 요소로 전달됩니다.

경고 : Next.js 14에서 사용 중단되었습니다. 대신 onLoad를 사용하세요.

이미지가 완전히 로드되고 placeholder가 제거되면 호출되는 콜백 함수입니다.

콜백 함수는 기본 <img> 요소에 대한 참조 하나를 인수로 받습니다.

<Image onLoadingComplete={(img) => console.log(img.naturalWidth)} />

next.config.js에서 Image 컴포넌트를 구성할 수 있습니다. 사용 가능한 옵션은 다음과 같습니다.

next.config.js 파일에서 localPatterns를 사용해 특정 로컬 경로의 이미지만 최적화하고 나머지는 차단합니다.

next.config.js

module.exports = {
images: {
localPatterns: [
{
pathname: '/assets/images/**',
search: '',
},
],
},
}

위 예시는 next/imagesrc 속성이 /assets/images/로 시작하고 쿼리 문자열이 없어야 함을 보장합니다. 다른 경로를 최적화하려 하면 400 Bad Request 오류가 발생합니다.

알아두면 좋아요 : search 속성을 생략하면 모든 검색 매개변수를 허용하게 되어 악의적인 사용자가 의도하지 않은 URL을 최적화할 수 있습니다. 정확히 일치하도록 search: '?v=2'처럼 구체적인 값을 사용하는 것이 좋습니다.

next.config.js에서 remotePatterns를 사용하면 특정 외부 경로의 이미지만 허용하고 나머지는 차단할 수 있습니다. 이렇게 하면 계정에서 제공되는 외부 이미지만 서빙됩니다.

next.config.js

module.exports = {
images: {
remotePatterns: [new URL('https://example.com/account123/**')],
},
}

객체 형태로도 remotePatterns를 설정할 수 있습니다:

next.config.js

module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
port: '',
pathname: '/account123/**',
search: '',
},
],
},
}

위 예시는 next/imagesrc 속성이 https://example.com/account123/로 시작하고 쿼리 문자열이 없어야 함을 보장합니다. 다른 프로토콜, 호스트명, 포트, 경로는 400 Bad Request를 반환합니다.

Wildcard Patterns:

와일드카드 패턴은 pathnamehostname 모두에 사용할 수 있으며 다음 구문을 갖습니다.

  • *: 하나의 경로 세그먼트 또는 서브도메인과 일치합니다.
  • **: 끝부분의 여러 경로 세그먼트 또는 시작 부분의 여러 서브도메인과 일치합니다. 패턴 중간에서는 사용할 수 없습니다.

next.config.js

module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '**.example.com',
port: '',
search: '',
},
],
},
}

이는 image.example.com 같은 서브도메인을 허용합니다. 쿼리 문자열과 사용자 지정 포트는 여전히 차단됩니다.

알아두면 좋아요 : protocol, port, pathname, search를 생략하면 와일드카드 **가 암묵적으로 적용됩니다. 의도하지 않은 URL이 최적화될 수 있으므로 권장하지 않습니다.

Query Strings :

search 속성을 사용해 쿼리 문자열도 제한할 수 있습니다:

next.config.js

module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'assets.example.com',
search: '?v=1727111025337',
},
],
},
}

위 예시는 next/imagesrc 속성이 https://assets.example.com으로 시작하고 정확한 쿼리 문자열 ?v=1727111025337을 가져야 함을 보장합니다. 다른 프로토콜이나 쿼리 문자열은 400 Bad Request를 반환합니다.

loaderFiles는 Next.js 대신 사용자 정의 이미지 최적화 서비스를 사용할 수 있게 해줍니다.

next.config.js

module.exports = {
images: {
loader: 'custom',
loaderFile: './my/image/loader.js',
},
}

경로는 프로젝트 루트 기준이어야 합니다. 파일은 URL 문자열을 반환하는 기본 함수를 export해야 합니다:

my/image/loader.js

export default function myImageLoader({ src, width, quality }) { return https://example.com/${src}?w=${width}&q=${quality || 75} }

예시:

또는 loader prop을 사용해 next/image의 각 인스턴스를 개별적으로 구성할 수 있습니다.

Image Optimization API의 기본 경로를 변경하거나 접두사를 추가하려면 path 속성을 사용하면 됩니다. path의 기본값은 /_next/image입니다.

next.config.js

module.exports = {
images: {
path: '/my-prefix/_next/image',
},
}

deviceSizes는 디바이스 너비 분기점을 나열할 수 있습니다. 이 너비들은 next/image 컴포넌트가 sizes prop을 사용할 때 사용자 디바이스에 맞는 이미지를 제공하도록 활용됩니다.

구성을 제공하지 않으면 아래 기본값이 사용됩니다.

next.config.js

module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
}

imageSizes는 이미지 너비 목록을 지정할 수 있습니다. 이 너비들은 device sizes 배열과 결합되어 이미지 srcset을 생성할 때 사용되는 전체 크기 배열을 만듭니다.

구성을 제공하지 않으면 아래 기본값이 사용됩니다.

next.config.js

module.exports = {
images: {
imageSizes: [32, 48, 64, 96, 128, 256, 384],
},
}

imageSizessizes prop을 제공하는 이미지에만 사용되며, 이는 해당 이미지가 화면 전체 너비보다 작음을 의미합니다. 따라서 imageSizes의 모든 값은 deviceSizes의 가장 작은 값보다 작아야 합니다.

qualities는 이미지 품질 값 목록을 지정할 수 있습니다.

구성을 제공하지 않으면 아래 기본값이 사용됩니다.

next.config.js

module.exports = {
images: {
qualities: [75],
},
}

알아두면 좋아요: Next.js 16부터는 이 필드가 필수입니다. 무제한 접근을 허용하면 악의적인 사용자가 의도한 것보다 더 많은 품질 값을 최적화할 수 있기 때문입니다.

허용 목록에 더 많은 이미지 품질 값을 추가할 수 있습니다. 예시는 다음과 같습니다.

next.config.js

module.exports = {
images: {
qualities: [25, 50, 75, 100],
},
}

위 예시에서는 25, 50, 75, 100 네 가지 품질만 허용됩니다.

quality prop이 이 배열의 값과 일치하지 않으면 가장 가까운 허용 값이 사용됩니다.

REST API를 직접 호출할 때 이 배열에 없는 품질을 지정하면 서버는 400 Bad Request 응답을 반환합니다.

formats는 사용할 이미지 포맷 목록을 지정할 수 있습니다.

next.config.js

module.exports = {
images: {
// Default
formats: ['image/webp'],
},
}

Next.js는 요청의 Accept 헤더를 통해 브라우저가 지원하는 이미지 포맷을 자동으로 감지해 최적의 출력 포맷을 결정합니다.

Accept 헤더가 구성된 포맷 중 둘 이상과 일치하면 배열에서 첫 번째로 일치하는 포맷이 사용되므로 배열 순서가 중요합니다. 일치하는 포맷이 없거나 원본 이미지가 애니메이션인 경우 원본 포맷이 사용됩니다.

브라우저가 AVIF를 지원하지 않는 경우 원본 포맷으로 폴백하도록 AVIF 지원을 활성화할 수 있습니다.

next.config.js

module.exports = {
images: {
formats: ['image/avif'],
},
}

AVIF와 WebP를 함께 활성화할 수도 있습니다. AVIF를 지원하는 브라우저에서는 AVIF가 우선이며 WebP가 폴백으로 사용됩니다.

next.config.js

module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
}

알아두면 좋아요 :

  • 대부분의 사용 사례에서는 여전히 WebP 사용을 권장합니다.
  • AVIF는 인코딩에 일반적으로 50% 더 오래 걸리지만 WebP보다 20% 더 작게 압축합니다. 즉, 이미지가 처음 요청될 때는 느릴 수 있지만, 캐시된 후의 후속 요청은 더 빠릅니다.
  • 여러 포맷을 사용할 경우 Next.js는 각 포맷을 별도로 캐시합니다. 이는 단일 포맷을 사용할 때보다 저장 요구량이 늘어나며, 브라우저 호환성을 위해 AVIF와 WebP 버전이 모두 저장됩니다.
  • Next.js 앞단에 Proxy/CDN을 두고 자체 호스팅하는 경우 Proxy가 Accept 헤더를 전달하도록 구성해야 합니다.

minimumCacheTTL은 캐시된 최적화 이미지의 TTL(Time to Live, 초 단위)을 구성할 수 있습니다. 많은 경우 Static Image Import를 사용하면 파일 내용을 해시하고 Cache-Control 헤더를 immutable로 설정해 이미지를 영구적으로 캐시하므로 더 적합합니다.

구성을 제공하지 않으면 아래 기본값이 사용됩니다.

next.config.js

module.exports = {
images: {
minimumCacheTTL: 14400, // 4 hours
},
}

TTL을 늘리면 재검증 횟수를 줄이고 비용을 낮출 수 있습니다.

next.config.js

module.exports = {
images: {
minimumCacheTTL: 2678400, // 31 days
},
}

최적화된 이미지의 만료(또는 Max Age)는 minimumCacheTTL과 업스트림 이미지의 Cache-Control 헤더 중 더 큰 값으로 결정됩니다.

이미지별로 캐싱 동작을 변경해야 한다면 headers를 구성해 업스트림 이미지(예: /some-asset.jpg, /_next/image 자체가 아님)에 Cache-Control 헤더를 설정할 수 있습니다.

현재 캐시를 무효화하는 메커니즘이 없으므로 minimumCacheTTL을 낮게 유지하는 것이 가장 좋습니다. 그렇지 않으면 src prop을 수동으로 변경하거나 <distDir>/cache/images의 캐시 파일을 삭제해야 할 수 있습니다.

disableStaticImages는 정적 이미지 import를 비활성화할 수 있습니다.

기본 동작에서는 import icon from './icon.png'처럼 정적 파일을 import한 후 src 속성에 전달할 수 있습니다. 때로는 이 기능이 다른 플러그인과 충돌해 import가 다르게 동작해야 하는 경우 비활성화하고 싶을 수 있습니다.

next.config.js에서 정적 이미지 import를 비활성화할 수 있습니다.

next.config.js

module.exports = {
images: {
disableStaticImages: true,
},
}

기본 이미지 최적화 로더는 원격 이미지를 가져올 때 최대 3번까지 HTTP 리디렉션을 따릅니다.

next.config.js

module.exports = {
images: {
maximumRedirects: 3,
},
}

원격 이미지를 가져올 때 따라갈 리디렉션 횟수를 구성할 수 있습니다. 값을 0으로 설정하면 리디렉션을 따르지 않습니다.

next.config.js

module.exports = {
images: {
maximumRedirects: 0,
},
}

기본 이미지 최적화 로더는 최대 50MB 크기의 소스 이미지를 가져옵니다.

next.config.js

module.exports = {
images: {
maximumResponseBody: 50_000_000,
},
}

모든 소스 이미지가 작다는 것을 알고 있다면, 값을 5MB와 같은 작은 값으로 낮춰 메모리가 제한된 서버를 보호할 수 있습니다.

next.config.js

module.exports = {
images: {
maximumResponseBody: 5_000_000,
},
}

사설 네트워크에서 Next.js를 자체 호스팅하는 드문 경우에는 동일 네트워크 내 로컬 IP 주소의 이미지를 최적화하도록 허용하고 싶을 수 있습니다. 내부 네트워크 콘텐츠에 악의적인 사용자가 접근할 수 있으므로 대부분의 사용자에게는 권장되지 않습니다.

기본값은 false입니다.

next.config.js

module.exports = {
images: {
dangerouslyAllowLocalIP: false,
},
}

로컬 네트워크의 다른 곳에 호스팅된 원격 이미지를 최적화해야 한다면 값을 true로 설정할 수 있습니다.

next.config.js

module.exports = {
images: {
dangerouslyAllowLocalIP: true,
},
}

dangerouslyAllowSVG는 SVG 이미지를 제공할 수 있도록 허용합니다.

next.config.js

module.exports = {
images: {
dangerouslyAllowSVG: true,
},
}

기본적으로 Next.js는 다음과 같은 이유로 SVG 이미지를 최적화하지 않습니다.

  • SVG는 벡터 포맷이므로 손실 없이 크기를 조정할 수 있습니다.
  • SVG는 HTML/CSS와 동일한 기능을 많이 제공하므로 적절한 Content Security Policy (CSP) 헤더가 없으면 취약점이 발생할 수 있습니다.

src prop이 SVG임을 알고 있을 때는 unoptimized prop을 사용하는 것이 좋습니다. src".svg"로 끝나면 자동으로 적용됩니다.

<Image src="/my-image.svg" unoptimized />

또한 브라우저가 이미지를 다운로드하도록 강제하기 위해 contentDispositionType을 설정하고, 이미지에 포함된 스크립트 실행을 방지하기 위해 contentSecurityPolicy도 설정하는 것이 강력히 권장됩니다.

next.config.js

module.exports = {
images: {
dangerouslyAllowSVG: true,
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
}

contentDispositionTypeContent-Disposition 헤더를 구성할 수 있습니다.

next.config.js

module.exports = {
images: {
contentDispositionType: 'inline',
},
}

contentSecurityPolicy는 이미지에 대한 Content-Security-Policy 헤더를 구성할 수 있습니다. 이는 이미지에 포함된 스크립트 실행을 방지하기 위한 dangerouslyAllowSVG 사용 시 특히 중요합니다.

next.config.js

module.exports = {
images: {
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
}

기본적으로 loader는 API가 임의의 원격 이미지를 제공할 수 있으므로 추가적인 보호를 위해 Content-Disposition 헤더를 attachment로 설정합니다.

기본값은 attachment이며, 이미지를 직접 방문할 때 브라우저가 해당 이미지를 다운로드하도록 강제합니다. 이는 dangerouslyAllowSVG가 true일 때 특히 중요합니다.

원한다면 inline을 구성하여 브라우저가 이미지를 직접 방문할 때 다운로드 없이 렌더링하도록 허용할 수 있습니다.

경고 : 악의적인 사용자로부터 애플리케이션을 보호하기 위해 엄격한 remotePatterns를 권장하면서 Next.js 14부터 더 이상 사용되지 않습니다.

remotePatterns와 유사하게 domains 구성은 외부 이미지에 대해 허용된 호스트 이름 목록을 제공하는 데 사용할 수 있습니다. 그러나 domains 구성은 와일드카드 패턴 매칭을 지원하지 않으며 프로토콜, 포트 또는 경로 이름을 제한할 수 없습니다.

대부분의 원격 이미지 서버는 여러 테넌트가 공유하므로, 의도한 이미지만 최적화되도록 remotePatterns를 사용하는 것이 더 안전합니다.

다음은 next.config.js 파일에서 domains 속성을 사용하는 예입니다:

next.config.js

module.exports = {
images: {
domains: ['assets.acme.com'],
},
}

getImageProps 함수는 내부 <img> 요소에 전달될 props를 가져와 다른 컴포넌트, 스타일, 캔버스 등에 전달할 때 사용할 수 있습니다.

import { getImageProps } from 'next/image'
const { props } = getImageProps({
src: 'https://example.com/image.jpg',
alt: 'A scenic mountain view',
width: 1200,
height: 800,
})
function ImageWithCaption() {
return (
<figure>
<img {...props} />
<figcaption>A scenic mountain view</figcaption>
</figure>
)
}

이는 React useState() 호출을 피하므로 성능 향상에 도움이 될 수 있지만, 플레이스홀더가 제거되지 않으므로 placeholder prop과 함께 사용할 수 없습니다.

next/image 컴포넌트는 브라우저 네이티브 지연 로딩을 사용하며, Safari 15.4 이전의 오래된 브라우저에서는 eager 로딩으로 폴백될 수 있습니다. blur-up 플레이스홀더를 사용할 때는 Safari 12 이전 브라우저에서 빈 플레이스홀더로 폴백합니다. width/heightauto인 스타일을 사용할 경우, 속성에서 종횡비를 유지하지 않는 Safari 15 이전 브라우저에서 Layout Shift가 발생할 수 있습니다. 자세한 내용은 이 MDN 동영상을 확인하세요.

Image 컴포넌트 스타일링은 일반 <img> 요소 스타일링과 비슷하지만 몇 가지 지침을 기억해야 합니다:

styled-jsx 대신 className 또는 style을 사용하세요. 대부분의 경우 className prop 사용을 권장합니다. 이는 가져온 CSS Module, 전역 스타일시트 등일 수 있습니다.

import styles from './styles.module.css'
export default function MyImage() {
return <Image className={styles.image} src="/my-image.png" alt="My Image" />
}

style prop을 사용해 인라인 스타일을 지정할 수도 있습니다.

export default function MyImage() {
return (
<Image style={{ borderRadius: '8px' }} src="/my-image.png" alt="My Image" />
)
}

fill을 사용할 때 부모 요소는 position: relative 또는 display: block이어야 합니다. 해당 레이아웃 모드에서 이미지 요소를 올바르게 렌더링하는 데 필요합니다.

<div style={{ position: 'relative' }}>
<Image fill src="/my-image.png" alt="My Image" />
</div>

styled-jsx는 현재 컴포넌트에 스코프되므로(global로 표시하지 않는 한) 사용할 수 없습니다.

정적 이미지를 import하면 Next.js는 파일을 기반으로 너비와 높이를 자동으로 설정합니다. 스타일을 설정해 이미지를 반응형으로 만들 수 있습니다:

import Image from 'next/image'
import mountains from '../public/mountains.jpg'
export default function Responsive() {
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<Image
alt="Mountains"
// Importing an image will
// automatically set the width and height
src={mountains}
sizes="100vw"
// Make the image display full width
// and preserve its aspect ratio
style={{
width: '100%',
height: 'auto',
}}
/>
</div>
)
}

소스 이미지가 동적이거나 원격 URL이라면, Next.js가 종횡비를 계산할 수 있도록 width와 height props를 제공해야 합니다:

components/page.js

import Image from 'next/image'
export default function Page({ photoUrl }) {
return (
<Image
src={photoUrl}
alt="Picture of the author"
sizes="100vw"
style={{
width: '100%',
height: 'auto',
}}
width={500}
height={300}
/>
)
}

직접 확인해 보세요:

이미지의 종횡비를 모를 경우 fill propobjectFit prop을 cover로 설정해 부모 컨테이너의 전체 너비를 채우게 만들 수 있습니다.

import Image from 'next/image'
import mountains from '../public/mountains.jpg'
export default function Fill() {
return (
<div
style={{
display: 'grid',
gridGap: '8px',
gridTemplateColumns: 'repeat(auto-fit, minmax(400px, auto))',
}}
>
<div style={{ position: 'relative', width: '400px' }}>
<Image
alt="Mountains"
src={mountains}
fill
sizes="(min-width: 808px) 50vw, 100vw"
style={{
objectFit: 'cover', // cover, contain, none
}}
/>
</div>
{/* And more images in the grid... */}
</div>
)
}

fill prop을 사용해 이미지가 화면 전체 영역을 덮도록 만들 수 있습니다:

import Image from 'next/image'
import mountains from '../public/mountains.jpg'
export default function Background() {
return (
<Image
alt="Mountains"
src={mountains}
placeholder="blur"
quality={100}
fill
sizes="100vw"
style={{
objectFit: 'cover',
}}
/>
)
}

다양한 스타일로 Image 컴포넌트를 사용하는 예시는 Image Component Demo에서 확인하세요.

원격 이미지를 사용하려면 src 속성을 URL 문자열로 지정해야 합니다.

app/page.js

import Image from 'next/image'
export default function Page() {
return (
<Image
src="https://s3.amazonaws.com/my-bucket/profile.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}

Next.js는 빌드 과정에서 원격 파일에 접근할 수 없으므로, width, height, 선택적인 blurDataURL props를 수동으로 제공해야 합니다.

widthheight 속성은 이미지의 올바른 종횡비를 추론해 로딩 중 레이아웃 시프트를 방지하는 데 사용됩니다. widthheight는 렌더링된 이미지 파일의 실제 크기를 결정하지 않습니다.

이미지를 안전하게 최적화하려면 next.config.js에 지원되는 URL 패턴 목록을 정의하세요. 악의적 사용을 방지하려면 가능한 한 구체적으로 지정해야 합니다. 예를 들어 아래 구성은 특정 AWS S3 버킷의 이미지만 허용합니다:

next.config.js

module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
search: '',
},
],
},
}

라이트 모드와 다크 모드에 서로 다른 이미지를 표시하고 싶다면, 두 개의 <Image> 컴포넌트를 감싼 새 컴포넌트를 만들고 CSS 미디어 쿼리에 따라 올바른 이미지를 노출할 수 있습니다.

components/theme-image.module.css

.imgDark {
display: none;
}
@media (prefers-color-scheme: dark) {

.imgLight { display: none; } .imgDark { display: unset; } }

components/theme-image.tsx

JavaScriptTypeScript

import styles from './theme-image.module.css'
import Image, { ImageProps } from 'next/image'
type Props = Omit<ImageProps, 'src' | 'preload' | 'loading'> & {
srcLight: string
srcDark: string
}
const ThemeImage = (props: Props) => {
const { srcLight, srcDark, ...rest } = props
return (
<>
<Image {...rest} src={srcLight} className={styles.imgLight} />
<Image {...rest} src={srcDark} className={styles.imgDark} />
</>
)
}

알아두면 좋아요: loading="lazy"의 기본 동작은 올바른 이미지 하나만 로드되도록 보장합니다. preloadloading="eager"를 사용하면 두 이미지가 모두 로드되므로 사용할 수 없습니다. 대신 fetchPriority="high"를 사용할 수 있습니다.

직접 사용해 보세요:

모바일과 데스크톱에 서로 다른 이미지를 표시하고 싶다면(이를 종종 Art Direction이라고 부릅니다) getImageProps()에 서로 다른 src, width, height, quality prop을 전달하면 됩니다.

app/page.js

import { getImageProps } from 'next/image'
export default function Home() {
const common = { alt: 'Art Direction Example', sizes: '100vw' }
const {
props: { srcSet: desktop },
} = getImageProps({
...common,
width: 1440,
height: 875,
quality: 80,
src: '/desktop.jpg',
})
const {
props: { srcSet: mobile, ...rest },
} = getImageProps({
...common,
width: 750,
height: 1334,
quality: 70,
src: '/mobile.jpg',
})
return (
<picture>
<source media="(min-width: 1000px)" srcSet={desktop} />
<source media="(min-width: 500px)" srcSet={mobile} />
<img {...rest} style={{ width: '100%', height: 'auto' }} />
</picture>
)
}

배경 이미지를 최적화하기 위해 srcSet 문자열을 image-set() CSS 함수로 변환할 수도 있습니다.

app/page.js

import { getImageProps } from 'next/image'
function getBackgroundImage(srcSet = '') {
const imageSet = srcSet
.split(', ')
.map((str) => {
const [url, dpi] = str.split(' ')
return `url("${url}") ${dpi}`
})
.join(', ')
return `image-set(${imageSet})`
}
export default function Home() {
const {
props: { srcSet },
} = getImageProps({ alt: '', width: 128, height: 128, src: '/img.png' })
const backgroundImage = getBackgroundImage(srcSet)
const style = { height: '100vh', width: '100vw', backgroundImage }
return (
<main style={style}>
<h1>Hello World</h1>
</main>
)
}
VersionChanges
v16.1.2maximumResponseBody 구성이 추가되었습니다.
v16.0.0qualities 기본 구성이 [75]로 변경되었고, preload prop이 추가되었으며, priority prop이 사용 중단되었습니다. dangerouslyAllowLocalIP 구성과 maximumRedirects 구성도 추가되었습니다.
v15.3.0remotePatternsURL 객체 배열을 지원합니다.
v15.0.0contentDispositionType 기본 구성 값이 attachment로 변경되었습니다.
v14.2.23qualities 구성이 추가되었습니다.
v14.2.15decoding prop과 localPatterns 구성이 추가되었습니다.
v14.2.14remotePatterns.search prop이 추가되었습니다.
v14.2.0overrideSrc prop이 추가되었습니다.
v14.1.0getImageProps()가 안정화되었습니다.
v14.0.0onLoadingComplete prop과 domains 구성이 사용 중단되었습니다.
v13.4.14placeholder prop이 data:/image...을 지원합니다.
v13.2.0contentDispositionType 구성이 추가되었습니다.
v13.0.6ref prop이 추가되었습니다.
v13.0.0next/image import가 next/legacy/image로 이름이 바뀌었고, next/future/image import가 next/image로 바뀌었습니다. import를 안전하게 자동 변경하기 위한 codemod가 제공됩니다. <span> 래퍼가 제거되었습니다. layout, objectFit, objectPosition, lazyBoundary, lazyRoot prop이 제거되었습니다. alt는 필수가 되었고 onLoadingCompleteimg 요소 참조를 받습니다. 내장 로더 구성도 제거되었습니다.
v12.3.0remotePatternsunoptimized 구성이 안정화되었습니다.
v12.2.0실험적 remotePatterns와 실험적 unoptimized 구성이 추가되었고 layout="raw"가 제거되었습니다.
v12.1.1style prop이 추가되고, layout="raw"에 대한 실험적 지원이 추가되었습니다.
v12.1.0dangerouslyAllowSVGcontentSecurityPolicy 구성이 추가되었습니다.
v12.0.9lazyRoot prop이 추가되었습니다.
v12.0.0formats 구성이 추가되었습니다.
AVIF 지원이 추가되었습니다.
래퍼 <div><span>으로 변경되었습니다.
v11.1.0onLoadingCompletelazyBoundary prop이 추가되었습니다.
v11.0.0src prop이 정적 import를 지원합니다.
placeholder prop이 추가되었습니다.
blurDataURL prop이 추가되었습니다.
v10.0.5loader prop이 추가되었습니다.
v10.0.1layout prop이 추가되었습니다.
v10.0.0next/image가 도입되었습니다.

보내기