문서
App Router 사용하기
컴포넌트
<Image>

<Image>

예제

이 API 참조는 Image 컴포넌트에 사용할 수 있는 props구성 옵션을 이해하는 데 도움이 될 것입니다. 기능과 사용법에 대해서는 Image 컴포넌트 페이지를 참조하세요.

app/page.js
import Image from "next/image";
 
export default function Page() {
  return (
    <Image src="/profile.png" width={500} height={500} alt="작성자의 사진" />
  );
}

Props

다음은 Image 컴포넌트에 사용할 수 있는 props의 요약입니다:

Prop예시타입필수 여부
srcsrc="/profile.png"String필수
widthwidth={500}Integer (px)필수
heightheight={500}Integer (px)필수
altalt="작성자의 사진"String필수
loaderloader={imageLoader}Function-
fillfill={true}Boolean-
sizessizes="(max-width: 768px) 100vw, 33vw"String-
qualityquality={80}Integer (1-100)-
prioritypriority={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-
overrideSrcoverrideSrc="/seo.png"String-

필수 Props

Image 컴포넌트는 다음 속성들을 필요로 합니다: src, alt, widthheight(또는 fill).

app/page.js
import Image from "next/image";
 
export default function Page() {
  return (
    <div>
      <Image src="/profile.png" width={500} height={500} alt="작성자의 사진" />
    </div>
  );
}

src

다음 중 하나여야 합니다:

  • 정적으로 가져온 이미지 파일
  • 경로 문자열. 이는 loader prop에 따라 절대 외부 URL이거나 내부 경로일 수 있습니다.

외부 URL을 사용할 때는 next.config.jsremotePatterns에 추가해야 합니다.

width

width 속성은 픽셀 단위로 이미지의 고유한 너비를 나타냅니다.

정적으로 가져온 이미지fill 속성을 사용하는 이미지를 제외하고는 필수입니다.

height

height 속성은 픽셀 단위로 이미지의 고유한 높이를 나타냅니다.

정적으로 가져온 이미지fill 속성을 사용하는 이미지를 제외하고는 필수입니다.

참고:

  • widthheight 속성은 함께 사용되어 이미지의 종횡비를 결정하며, 이는 브라우저가 이미지가 로드되기 전에 공간을 예약하는 데 사용됩니다.
  • 본질적인 크기가 항상 브라우저에서 렌더링되는 크기를 의미하는 것은 아니며, 이는 부모 컨테이너에 의해 결정됩니다. 예를 들어, 부모 컨테이너가 본질적인 크기보다 작다면 이미지는 컨테이너에 맞게 축소됩니다.
  • 너비와 높이를 모를 때는 fill 속성을 사용할 수 있습니다.

alt

alt 속성은 스크린 리더와 검색 엔진이 이미지를 설명하는 데 사용됩니다. 또한 이미지가 비활성화되었거나 이미지 로딩 중 오류가 발생한 경우 대체 텍스트로 사용됩니다.

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

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

자세히 알아보기

선택적 Props

<Image /> 컴포넌트는 필수 속성 외에도 여러 추가 속성을 받아들입니다. 이 섹션에서는 Image 컴포넌트의 가장 일반적으로 사용되는 속성들에 대해 설명합니다. 더 드물게 사용되는 속성들에 대한 자세한 내용은 고급 Props 섹션에서 찾을 수 있습니다.

loader

이미지 URL을 해결하는 데 사용되는 사용자 정의 함수입니다.

loader는 다음 매개변수를 받아 이미지의 URL 문자열을 반환하는 함수입니다:

다음은 사용자 정의 로더를 사용하는 예시입니다:

"use client";
 
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}
    />
  );
}

참고: 함수를 받는 loader와 같은 props를 사용하려면 제공된 함수를 직렬화하기 위해 클라이언트 컴포넌트를 사용해야 합니다.

또는 next.config.jsloaderFile 구성을 사용하여 prop을 전달하지 않고도 애플리케이션의 모든 next/image 인스턴스를 구성할 수 있습니다.

fill

fill={true} // {true} | {false}

이미지가 부모 요소를 채우도록 하는 부울 값으로, widthheight를 모를 때 유용합니다.

부모 요소는 반드시 position: "relative", position: "fixed", 또는 position: "absolute" 스타일을 할당해야 합니다.

기본적으로 img 요소에는 자동으로 position: "absolute" 스타일이 할당됩니다.

이미지에 스타일이 적용되지 않으면 이미지는 컨테이너에 맞게 늘어납니다. 컨테이너에 맞추면서도 종횡비를 유지하고 싶다면 object-fit: "contain"을 설정하는 것이 좋을 수 있습니다.

또는 object-fit: "cover"를 사용하면 이미지가 전체 컨테이너를 채우고 종횡비를 유지하기 위해 잘립니다.

자세한 정보는 다음을 참조하세요:

sizes

미디어 쿼리와 유사한 문자열로, 다양한 중단점에서 이미지의 너비가 얼마나 될지에 대한 정보를 제공합니다. fill을 사용하거나 반응형 크기로 스타일링된 이미지의 경우 sizes 값이 성능에 큰 영향을 미칩니다.

sizes 속성은 이미지 성능과 관련하여 두 가지 중요한 목적을 수행합니다:

  • 첫째, sizes 값은 브라우저가 next/image의 자동 생성된 srcset에서 어떤 크기의 이미지를 다운로드할지 결정하는 데 사용됩니다. 브라우저가 선택할 때, 아직 페이지의 이미지 크기를 알지 못하므로 뷰포트와 같거나 더 큰 크기의 이미지를 선택합니다. sizes 속성을 사용하면 브라우저에게 이미지가 실제로 전체 화면보다 작을 것이라고 알려줄 수 있습니다. fill 속성이 있는 이미지에 sizes 값을 지정하지 않으면 기본값 100vw(전체 화면 너비)가 사용됩니다.
  • 둘째, sizes 속성은 자동 생성된 srcset 값의 동작을 변경합니다. sizes 값이 없으면 고정 크기 이미지에 적합한 작은 srcset이 생성됩니다(1x/2x/등). sizes가 정의되면 반응형 이미지에 적합한 큰 srcset이 생성됩니다(640w/750w/등). sizes 속성에 50vw와 같은 뷰포트 너비의 백분율을 나타내는 크기가 포함된 경우, srcset은 너무 작아서 필요하지 않은 값을 포함하지 않도록 잘립니다.

예를 들어, 스타일링으로 인해 이미지가 모바일 기기에서는 전체 너비로, 태블릿에서는 2열 레이아웃으로, 데스크톱 디스플레이에서는 3열 레이아웃으로 표시될 것을 알고 있다면 다음과 같은 sizes 속성을 포함해야 합니다:

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는 성능 지표에 극적인 영향을 미칠 수 있습니다. 33vw sizes 없이는 서버에서 선택된 이미지가 필요한 것보다 3배 더 넓을 것입니다. 파일 크기는 너비의 제곱에 비례하므로, sizes 없이는 사용자가 필요한 것보다 9배 더 큰 이미지를 다운로드하게 됩니다.

srcsetsizes에 대해 더 자세히 알아보기:

quality

quality={75} // {number 1-100}

최적화된 이미지의 품질로, 1에서 100 사이의 정수입니다. 100이 가장 좋은 품질이므로 가장 큰 파일 크기입니다. 기본값은 75입니다.

priority

priority={false} // {false} | {true}

true일 때, 이미지는 높은 우선순위로 간주되며 preload됩니다. priority를 사용하는 이미지에 대해서는 지연 로딩이 자동으로 비활성화됩니다.

Largest Contentful Paint (LCP) 요소로 감지된 모든 이미지에 priority 속성을 사용해야 합니다. 다양한 뷰포트 크기에 대해 다른 이미지가 LCP 요소일 수 있으므로 여러 개의 우선순위 이미지를 갖는 것이 적절할 수 있습니다.

이미지가 폴드 위에 보이는 경우에만 사용해야 합니다. 기본값은 false입니다.

placeholder

placeholder = "empty"; // "empty" | "blur" | "data:image/..."

이미지가 로딩되는 동안 사용할 플레이스홀더입니다. 가능한 값은 blur, empty, 또는 data:image/...입니다. 기본값은 empty입니다.

blur일 때, blurDataURL 속성이 플레이스홀더로 사용됩니다. src정적 임포트의 객체이고 가져온 이미지가 .jpg, .png, .webp, 또는 .avif인 경우, blurDataURL은 자동으로 채워집니다. 단, 이미지가 애니메이션인 것으로 감지된 경우는 제외됩니다.

동적 이미지의 경우, blurDataURL 속성을 제공해야 합니다. Plaiceholder와 같은 솔루션이 base64 생성에 도움이 될 수 있습니다.

data:image/...일 때, 이미지가 로딩되는 동안 Data URL이 플레이스홀더로 사용됩니다.

empty일 때, 이미지가 로딩되는 동안 플레이스홀더가 없으며 빈 공간만 있습니다.

시도해 보세요:

고급 Props

일부 경우에는 더 고급 사용법이 필요할 수 있습니다. <Image /> 컴포넌트는 선택적으로 다음과 같은 고급 속성을 받아들입니다.

style

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

components/ProfileImage.js
const imageStyle = {
  borderRadius: "50%",
  border: "1px solid #fff",
};
 
export default function ProfileImage() {
  return <Image src="..." style={imageStyle} />;
}

필수 너비와 높이 props가 스타일링과 상호작용할 수 있다는 점을 기억하세요. 스타일링을 사용하여 이미지의 너비를 수정하는 경우, 고유한 종횡비를 유지하기 위해 높이도 auto로 스타일링해야 합니다. 그렇지 않으면 이미지가 왜곡됩니다.

onLoadingComplete

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

경고: Next.js 14에서 onLoad로 대체되었습니다.

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

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

참고: 함수를 받는 onLoadingComplete와 같은 props를 사용하려면 제공된 함수를 직렬화하기 위해 클라이언트 컴포넌트를 사용해야 합니다.

onLoad

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

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

콜백 함수는 기본 <img> 요소를 참조하는 target을 가진 Event를 하나의 인수로 받습니다.

참고: 함수를 받는 onLoad와 같은 props를 사용하려면 제공된 함수를 직렬화하기 위해 클라이언트 컴포넌트를 사용해야 합니다.

onError

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

이미지 로딩에 실패한 경우 호출되는 콜백 함수입니다.

참고: 함수를 받는 onError와 같은 props를 사용하려면 제공된 함수를 직렬화하기 위해 클라이언트 컴포넌트를 사용해야 합니다.

loading

권장사항: 이 속성은 고급 사용 사례에만 사용됩니다. 이미지를 eager로 로드하도록 전환하면 일반적으로 성능이 저하됩니다. 대신 priority 속성을 사용하는 것이 좋습니다. 이는 이미지를 미리 로드합니다.

loading = "lazy"; // {lazy} | {eager}

이미지의 로딩 동작입니다. 기본값은 lazy입니다.

lazy일 때, 뷰포트로부터 계산된 거리에 도달할 때까지 이미지 로딩을 지연시킵니다.

eager일 때, 이미지를 즉시 로드합니다.

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

blurDataURL

src 이미지가 성공적으로 로드되기 전에 플레이스홀더 이미지로 사용할 Data URL입니다. placeholder="blur"와 함께 사용할 때만 효과가 있습니다.

반드시 base64로 인코딩된 이미지여야 합니다. 확대되고 흐려지므로 매우 작은 이미지(10px 이하)를 권장합니다. 플레이스홀더로 더 큰 이미지를 포함하면 애플리케이션 성능에 해를 끼칠 수 있습니다.

시도해 보세요:

단색 Data URL을 생성하여 이미지와 일치시킬 수도 있습니다.

unoptimized

unoptimized = {false} // {false} | {true}

true일 때, 품질, 크기 또는 형식을 변경하지 않고 소스 이미지가 그대로 제공됩니다. 기본값은 false입니다.

import Image from "next/image";
 
const UnoptimizedImage = (props) => {
  return <Image {...props} unoptimized />;
};

Next.js 12.3.0부터 이 prop은 다음 구성으로 next.config.js를 업데이트하여 모든 이미지에 할당할 수 있습니다:

next.config.js
module.exports = {
  images: {
    unoptimized: true,
  },
};

overrideSrc

<Image> 컴포넌트에 src prop을 제공할 때, 결과로 나오는 <img>에 대해 srcsetsrc 속성이 자동으로 생성됩니다.

input.js
<Image src="/me.jpg" />
output.html
<img
  srcset="
    /_next/image?url=%2Fme.jpg&w=640&q=75 1x,
    /_next/image?url=%2Fme.jpg&w=828&q=75 2x
  "
  src="/_next/image?url=%2Fme.jpg&w=828&q=75"
/>

일부 경우에는 src 속성이 생성되는 것이 바람직하지 않을 수 있으며, overrideSrc prop을 사용하여 이를 재정의하고 싶을 수 있습니다.

예를 들어, 기존 웹사이트를 <img>에서 <Image>로 업그레이드할 때, 이미지 랭킹이나 재크롤 방지와 같은 SEO 목적으로 동일한 src 속성을 유지하고 싶을 수 있습니다.

input.js
<Image src="/me.jpg" overrideSrc="/override.jpg" />
output.html
<img
  srcset="
    /_next/image?url=%2Fme.jpg&w=640&q=75 1x,
    /_next/image?url=%2Fme.jpg&w=828&q=75 2x
  "
  src="/override.jpg"
/>

기타 Props

다음을 제외한 <Image /> 컴포넌트의 다른 속성들은 기본 img 요소로 전달됩니다:

  • srcSet. 대신 Device Sizes를 사용하세요.
  • decoding. 항상 "async"입니다.

구성 옵션

props 외에도 next.config.js에서 Image Component를 구성할 수 있습니다. 다음과 같은 옵션을 사용할 수 있습니다:

remotePatterns

악의적인 사용자로부터 애플리케이션을 보호하기 위해 외부 이미지를 사용하려면 구성이 필요합니다. 이는 Next.js Image Optimization API에서 귀하의 계정의 외부 이미지만 제공될 수 있도록 합니다. 이러한 외부 이미지는 아래와 같이 next.config.js 파일의 remotePatterns 속성으로 구성할 수 있습니다:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "example.com",
        port: "",
        pathname: "/account123/**",
      },
    ],
  },
};

참고: 위의 예시는 next/imagesrc 속성이 https://example.com/account123/로 시작해야 함을 보장합니다. 다른 프로토콜, 호스트 이름, 포트 또는 일치하지 않는 경로는 400 Bad Request로 응답합니다.

다음은 next.config.js 파일의 remotePatterns 속성의 또 다른 예시입니다:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "**.example.com",
        port: "",
      },
    ],
  },
};

참고: 위의 예시는 next/imagesrc 속성이 https://img1.example.com 또는 https://me.avatar.example.com 또는 임의의 수의 하위 도메인으로 시작해야 함을 보장합니다. 다른 프로토콜, 포트 또는 일치하지 않는 호스트 이름은 400 Bad Request로 응답합니다.

와일드카드 패턴은 pathnamehostname 모두에 사용될 수 있으며 다음과 같은 구문을 가집니다:

  • * 단일 경로 세그먼트 또는 하위 도메인과 일치
  • ** 끝에 있는 여러 경로 세그먼트 또는 시작 부분의 하위 도메인과 일치

** 구문은 패턴의 중간에서는 작동하지 않습니다.

참고: protocol, port 또는 pathname을 생략하면 와일드카드 **가 암시됩니다. 이는 악의적인 행위자가 의도하지 않은 URL을 최적화할 수 있으므로 권장되지 않습니다.

domains

경고: Next.js 14에서 악의적인 사용자로부터 애플리케이션을 보호하기 위해 엄격한 remotePatterns로 대체되었습니다. 도메인의 모든 콘텐츠를 소유한 경우에만 domains를 사용하세요.

remotePatterns와 유사하게 domains 구성을 사용하여 외부 이미지에 대해 허용된 호스트 이름 목록을 제공할 수 있습니다.

그러나 domains 구성은 와일드카드 패턴 매칭을 지원하지 않으며 프로토콜, 포트 또는 경로 이름을 제한할 수 없습니다.

다음은 next.config.js 파일의 domains 속성 예시입니다:

next.config.js
module.exports = {
  images: {
    domains: ["assets.acme.com"],
  },
};

loaderFile

Next.js 내장 Image Optimization API 대신 클라우드 제공업체를 사용하여 이미지를 최적화하려면 next.config.js에서 다음과 같이 loaderFile을 구성할 수 있습니다:

next.config.js
module.exports = {
  images: {
    loader: "custom",
    loaderFile: "./my/image/loader.js",
  },
};

이는 Next.js 애플리케이션의 루트를 기준으로 한 파일을 가리켜야 합니다. 파일은 문자열을 반환하는 기본 함수를 내보내야 합니다. 예를 들어:

my/image/loader.js
"use client";
 
export default function myImageLoader({ src, width, quality }) {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
}

또는 loader prop을 사용하여 각 next/image 인스턴스를 구성할 수 있습니다.

예시:

참고: 함수를 받는 사용자 정의 이미지 로더 파일을 사용자 정의하려면 제공된 함수를 직렬화하기 위해 클라이언트 컴포넌트를 사용해야 합니다.

고급

다음 구성은 고급 사용 사례를 위한 것이며 일반적으로 필요하지 않습니다. 아래 속성을 구성하기로 선택한 경우, 향후 업데이트에서 Next.js 기본값에 대한 모든 변경 사항을 재정의하게 됩니다.

deviceSizes

사용자의 예상 기기 너비를 알고 있다면 next.config.jsdeviceSizes 속성을 사용하여 기기 너비 중단점 목록을 지정할 수 있습니다. 이러한 너비는 next/image 컴포넌트가 sizes prop을 사용할 때 사용자의 기기에 맞는 올바른 이미지가 제공되도록 하는 데 사용됩니다.

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

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

imageSizes

next.config.js 파일의 images.imageSizes 속성을 사용하여 이미지 너비 목록을 지정할 수 있습니다. 이러한 너비는 기기 크기 배열과 연결되어 이미지 srcset를 생성하는 데 사용되는 전체 크기 배열을 형성합니다.

두 개의 개별 목록이 있는 이유는 imageSizes가 화면의 전체 너비보다 작은 이미지를 나타내는 sizes prop을 제공하는 이미지에만 사용되기 때문입니다. 따라서 imageSizes의 크기는 모두 deviceSizes의 가장 작은 크기보다 작아야 합니다.

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

next.config.js
module.exports = {
  images: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
};

formats

기본 Image Optimization API는 요청의 Accept 헤더를 통해 브라우저가 지원하는 이미지 형식을 자동으로 감지합니다.

Accept 헤더가 구성된 형식 중 둘 이상과 일치하면 배열의 첫 번째 일치 항목이 사용됩니다. 따라서 배열 순서가 중요합니다. 일치하는 항목이 없거나 소스 이미지가 애니메이션인 경우 Image Optimization API는 원본 이미지의 형식으로 폴백합니다.

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

next.config.js
module.exports = {
  images: {
    formats: ["image/webp"],
  },
};

다음 구성으로 AVIF 지원을 활성화할 수 있습니다.

next.config.js
module.exports = {
  images: {
    formats: ["image/avif", "image/webp"],
  },
};

참고:

  • AVIF는 일반적으로 인코딩하는 데 20% 더 오래 걸리지만 WebP보다 20% 더 작게 압축됩니다. 즉, 이미지가 처음 요청될 때는 일반적으로 더 느리지만 이후 캐시된 요청은 더 빠를 것입니다.
  • Next.js 앞에 프록시/CDN을 사용하여 자체 호스팅하는 경우, 프록시가 Accept 헤더를 전달하도록 구성해야 합니다.

캐싱 동작

다음은 기본 로더의 캐싱 알고리즘을 설명합니다. 다른 모든 로더의 경우 클라우드 제공업체의 문서를 참조하세요.

이미지는 요청 시 동적으로 최적화되어 <distDir>/cache/images 디렉토리에 저장됩니다. 최적화된 이미지 파일은 만료 시까지 후속 요청에 제공됩니다. 캐시되었지만 만료된 파일과 일치하는 요청이 이루어지면 만료된 이미지가 즉시 오래된 상태로 제공됩니다. 그런 다음 이미지는 백그라운드에서 다시 최적화되고(이를 재검증이라고도 함) 새로운 만료 날짜와 함께 캐시에 저장됩니다.

이미지의 캐시 상태는 x-nextjs-cache 응답 헤더의 값을 읽어 확인할 수 있습니다. 가능한 값은 다음과 같습니다:

  • MISS - 경로가 캐시에 없음 (최대 한 번, 첫 방문 시 발생)
  • STALE - 경로가 캐시에 있지만 재검증 시간을 초과하여 백그라운드에서 업데이트됨
  • HIT - 경로가 캐시에 있고 재검증 시간을 초과하지 않음

만료(또는 Max Age)는 minimumCacheTTL 구성 또는 업스트림 이미지 Cache-Control 헤더 중 더 큰 값으로 정의됩니다. 구체적으로 Cache-Control 헤더의 max-age 값이 사용됩니다. s-maxagemax-age가 모두 발견되면 s-maxage가 선호됩니다. max-age는 또한 CDN 및 브라우저를 포함한 모든 다운스트림 클라이언트에 전달됩니다.

  • 업스트림 이미지에 Cache-Control 헤더가 포함되지 않았거나 값이 매우 낮은 경우 minimumCacheTTL을 구성하여 캐시 기간을 늘릴 수 있습니다.
  • deviceSizesimageSizes를 구성하여 생성 가능한 총 이미지 수를 줄일 수 있습니다.
  • formats을 구성하여 단일 이미지 형식을 선호하여 여러 형식을 비활성화할 수 있습니다.

minimumCacheTTL

캐시된 최적화 이미지의 Time to Live (TTL)를 초 단위로 구성할 수 있습니다. 많은 경우에 파일 내용을 자동으로 해시하고 Cache-Control 헤더가 immutable인 이미지를 영구적으로 캐시하는 정적 이미지 가져오기를 사용하는 것이 더 좋습니다.

next.config.js
module.exports = {
  images: {
    minimumCacheTTL: 60,
  },
};

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

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

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

disableStaticImages

기본 동작은 import icon from './icon.png'와 같은 정적 파일을 가져온 다음 이를 src 속성에 전달할 수 있게 합니다.

일부 경우에는 이 기능이 다른 플러그인과 충돌하여 가져오기가 다르게 동작하기를 기대하는 경우 이 기능을 비활성화하고 싶을 수 있습니다.

next.config.js 내에서 정적 이미지 가져오기를 비활성화할 수 있습니다:

next.config.js
module.exports = {
  images: {
    disableStaticImages: true,
  },
};

dangerouslyAllowSVG

기본 로더는 몇 가지 이유로 SVG 이미지를 최적화하지 않습니다. 첫째, SVG는 손실 없이 크기를 조정할 수 있는 벡터 형식입니다. 둘째, SVG는 적절한 콘텐츠 보안 정책(CSP) 헤더가 없으면 취약성으로 이어질 수 있는 HTML/CSS와 많은 동일한 기능을 가지고 있습니다.

따라서 src prop이 SVG인 것으로 알려진 경우 unoptimized prop을 사용하는 것이 좋습니다. 이는 src.svg로 끝나는 경우 자동으로 발생합니다.

그러나 기본 Image Optimization API로 SVG 이미지를 제공해야 하는 경우 next.config.js에서 dangerouslyAllowSVG를 설정할 수 있습니다:

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

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

contentDispositionType

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

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

선택적으로 inline을 구성하여 브라우저가 직접 방문할 때 다운로드하지 않고 이미지를 렌더링하도록 할 수 있습니다.

next.config.js
module.exports = {
  images: {
    contentDispositionType: "inline",
  },
};

애니메이션 이미지

기본 로더는 자동으로 애니메이션 이미지에 대해 Image Optimization을 우회하고 이미지를 그대로 제공합니다.

애니메이션 파일에 대한 자동 감지는 최선의 노력이며 GIF, APNG 및 WebP를 지원합니다. 주어진 애니메이션 이미지에 대해 명시적으로 Image Optimization을 우회하려면 unoptimized prop을 사용하세요.

반응형 이미지

기본적으로 생성된 srcset은 다양한 기기 픽셀 비율을 지원하기 위해 1x2x 이미지를 포함합니다. 그러나 뷰포트와 함께 늘어나는 반응형 이미지를 렌더링하고 싶을 수 있습니다. 이 경우 sizesstyle(또는 className)을 설정해야 합니다.

아래 방법 중 하나를 사용하여 반응형 이미지를 렌더링할 수 있습니다.

정적 가져오기를 사용한 반응형 이미지

소스 이미지가 동적이지 않은 경우 정적으로 가져와 반응형 이미지를 만들 수 있습니다:

components/author.js
import Image from "next/image";
import me from "../photos/me.jpg";
 
export default function Author() {
  return (
    <Image
      src={me}
      alt="작성자의 사진"
      sizes="100vw"
      style={{
        width: "100%",
        height: "auto",
      }}
    />
  );
}

시도해 보세요:

종횡비가 있는 반응형 이미지

소스 이미지가 동적이거나 원격 URL인 경우, 반응형 이미지의 올바른 종횡비를 설정하기 위해 widthheight도 제공해야 합니다:

components/page.js
import Image from "next/image";
 
export default function Page({ photoUrl }) {
  return (
    <Image
      src={photoUrl}
      alt="작성자의 사진"
      sizes="100vw"
      style={{
        width: "100%",
        height: "auto",
      }}
      width={500}
      height={300}
    />
  );
}

시도해 보세요:

fill을 사용한 반응형 이미지

종횡비를 모르는 경우 fill prop을 설정하고 부모에 position: relative를 설정해야 합니다. 선택적으로 원하는 늘림 vs 자르기 동작에 따라 object-fit 스타일을 설정할 수 있습니다:

app/page.js
import Image from "next/image";
 
export default function Page({ photoUrl }) {
  return (
    <div style={{ position: "relative", width: "300px", height: "500px" }}>
      <Image
        src={photoUrl}
        alt="작성자의 사진"
        sizes="300px"
        fill
        style={{
          objectFit: "contain",
        }}
      />
    </div>
  );
}

시도해 보세요:

테마 감지 CSS

라이트 모드와 다크 모드에 대해 다른 이미지를 표시하려면 두 개의 <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
import styles from "./theme-image.module.css";
import Image, { ImageProps } from "next/image";
 
type Props = Omit<ImageProps, "src" | "priority" | "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} />
    </>
  );
};
components/theme-image.js
import styles from "./theme-image.module.css";
import Image from "next/image";
 
const ThemeImage = (props) => {
  const { srcLight, srcDark, ...rest } = props;
 
  return (
    <>
      <Image {...rest} src={srcLight} className={styles.imgLight} />
      <Image {...rest} src={srcDark} className={styles.imgDark} />
    </>
  );
};

참고: loading="lazy"의 기본 동작은 올바른 이미지만 로드되도록 합니다. priority 또는 loading="eager"를 사용할 수 없습니다. 그렇게 하면 두 이미지가 모두 로드되기 때문입니다. 대신 fetchPriority="high"를 사용할 수 있습니다.

시도해 보세요:

getImageProps

더 고급 사용 사례의 경우, getImageProps()를 호출하여 기본 <img> 요소에 전달될 props를 가져온 다음 이를 다른 컴포넌트, 스타일, 캔버스 등에 전달할 수 있습니다.

이는 또한 React useState()를 호출하지 않으므로 더 나은 성능으로 이어질 수 있지만, placeholder prop과 함께 사용할 수 없습니다. 플레이스홀더가 제거되지 않기 때문입니다.

테마 감지 Picture

라이트 모드와 다크 모드에 대해 다른 이미지를 표시하려면 <picture> 요소를 사용하여 사용자의 선호 색 구성표에 따라 다른 이미지를 표시할 수 있습니다.

app/page.js
import { getImageProps } from "next/image";
 
export default function Page() {
  const common = { alt: "테마 예시", width: 800, height: 400 };
  const {
    props: { srcSet: dark },
  } = getImageProps({ ...common, src: "/dark.png" });
  const {
    props: { srcSet: light, ...rest },
  } = getImageProps({ ...common, src: "/light.png" });
 
  return (
    <picture>
      <source media="(prefers-color-scheme: dark)" srcSet={dark} />
      <source media="(prefers-color-scheme: light)" srcSet={light} />
      <img {...rest} />
    </picture>
  );
}

아트 디렉션

모바일과 데스크톱에 대해 다른 이미지를 표시하려면 (때로는 아트 디렉션이라고 함) getImageProps()에 다른 src, width, height, 및 quality props를 제공할 수 있습니다.

app/page.js
import { getImageProps } from "next/image";
 
export default function Home() {
  const common = { alt: "아트 디렉션 예시", 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>
  );
}

배경 CSS

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

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>
  );
}

알려진 브라우저 버그

next/image 컴포넌트는 브라우저 네이티브 지연 로딩을 사용하며, Safari 15.4 이전의 구형 브라우저에서는 즉시 로딩으로 폴백될 수 있습니다. 블러 업 플레이스홀더를 사용할 때, Safari 12 이전의 구형 브라우저는 빈 플레이스홀더로 폴백됩니다. width/heightauto인 스타일을 사용할 때, 종횡비를 보존하지 않는 Safari 15 이전의 구형 브라우저에서 레이아웃 시프트를 일으킬 수 있습니다. 자세한 내용은 이 MDN 비디오를 참조하세요.

  • Safari 15 - 16.3은 로딩 중에 회색 테두리를 표시합니다. Safari 16.4는 이 문제를 해결했습니다. 가능한 해결책:
    • CSS @supports (font: -apple-system-body) and (-webkit-appearance: none) { img[loading="lazy"] { clip-path: inset(0.6px) } } 사용
    • 이미지가 폴드 위에 있는 경우 priority 사용
  • Firefox 67+는 로딩 중에 흰색 배경을 표시합니다. 가능한 해결책:

버전 기록

버전변경 사항
v15.0.0contentDispositionType 구성 기본값이 attachment로 변경되었습니다.
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 가져오기가 next/legacy/image로 이름이 변경되었습니다. next/future/image 가져오기가 next/image로 이름이 변경되었습니다. 가져오기를 안전하고 자동으로 이름을 변경하기 위한 codemod가 사용 가능합니다. <span> 래퍼가 제거되었습니다. layout, objectFit, objectPosition, lazyBoundary, lazyRoot props가 제거되었습니다. 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 props가 추가되었습니다.
v11.0.0src prop이 정적 가져오기를 지원합니다.
placeholder prop이 추가되었습니다.
blurDataURL prop이 추가되었습니다.
v10.0.5loader prop이 추가되었습니다.
v10.0.1layout prop이 추가되었습니다.
v10.0.0next/image가 도입되었습니다.