Image (舊版)

從 Next.js 13 開始,next/image 元件經過重寫以提升效能和開發者體驗。為了提供向後相容的升級方案,舊版 next/image 已更名為 next/legacy/image

檢視新版 next/image API 參考文件

比較

next/legacy/image 相比,新版 next/image 元件有以下變更:

  • 移除 <img> 周圍的 <span> 包裝,改用原生的計算寬高比
  • 新增對標準 style prop 的支援
    • 移除 layout prop,改用 styleclassName
    • 移除 objectFit prop,改用 styleclassName
    • 移除 objectPosition prop,改用 styleclassName
  • 移除 IntersectionObserver 實作,改用原生延遲載入
    • 移除 lazyBoundary prop,因為沒有原生等效項
    • 移除 lazyRoot prop,因為沒有原生等效項
  • 移除 loader 配置,改用 loader prop
  • alt prop 從可選改為必填
  • 變更 onLoadingComplete 回調函式,使其接收 <img> 元素的參考

必要屬性

<Image /> 元件需要以下屬性。

src

必須是以下其中一項:

使用預設 loader 時,還需考慮以下來源圖片情況:

  • 當 src 是外部 URL 時,必須配置 remotePatterns
  • 當 src 是動畫圖片或非已知格式 (JPEG、PNG、WebP、AVIF、GIF、TIFF) 時,圖片將按原樣提供
  • 當 src 是 SVG 格式時,除非啟用 unoptimizeddangerouslyAllowSVG,否則將被阻止

width

width 屬性可表示 渲染 寬度或 原始 寬度(像素),取決於 layoutsizes 屬性。

使用 layout="intrinsic"layout="fixed" 時,width 屬性表示 渲染 寬度(像素),因此會影響圖片顯示的大小。

使用 layout="responsive"layout="fill" 時,width 屬性表示 原始 寬度(像素),因此只會影響寬高比。

width 屬性是必填的,除非是靜態匯入的圖片或使用 layout="fill" 的情況。

height

height 屬性可表示 渲染 高度或 原始 高度(像素),取決於 layoutsizes 屬性。

使用 layout="intrinsic"layout="fixed" 時,height 屬性表示 渲染 高度(像素),因此會影響圖片顯示的大小。

使用 layout="responsive"layout="fill" 時,height 屬性表示 原始 高度(像素),因此只會影響寬高比。

height 屬性是必填的,除非是靜態匯入的圖片或使用 layout="fill" 的情況。

可選屬性

<Image /> 元件接受許多額外屬性。本節描述 Image 元件最常用的屬性。更多較少使用的屬性詳情請參閱進階屬性一節。

layout

圖片在視口大小變化時的佈局行為。

layout行為srcSetsizes有包裝和尺寸調整器
intrinsic (預設)縮小以適應容器寬度,最大不超過圖片原始尺寸1x, 2x (基於 imageSizes)N/A
fixed嚴格按照 widthheight 設定尺寸1x, 2x (基於 imageSizes)N/A
responsive縮放以適應容器寬度640w, 750w, ... 2048w, 3840w (基於 imageSizesdeviceSizes)100vw
fill在 X 和 Y 軸上延伸以填滿容器640w, 750w, ... 2048w, 3840w (基於 imageSizesdeviceSizes)100vw
  • 演示 intrinsic 佈局 (預設)
    • intrinsic 時,圖片會針對較小的視口縮小尺寸,但對較大的視口保持原始尺寸。
  • 演示 fixed 佈局
    • fixed 時,圖片尺寸不會隨視口變化而改變(無響應性),類似於原生的 img 元素。
  • 演示 responsive 佈局
    • responsive 時,圖片會針對較小的視口縮小尺寸,並針對較大的視口放大尺寸。
    • 確保父元素在樣式表中使用 display: block
  • 演示 fill 佈局
    • fill 時,圖片會在寬度和高度上延伸以符合父元素的尺寸,前提是父元素是相對定位。
    • 這通常與 objectFit 屬性搭配使用。
    • 確保父元素在樣式表中具有 position: relative
  • 演示背景圖片

loader

用於解析 URL 的自訂函式。在 Image 元件上設定 loader prop 會覆蓋 next.config.jsimages 區段中定義的預設 loader。

loader 是一個函式,根據以下參數返回圖片的 URL 字串:

以下是使用自訂 loader 的範例:

import Image from 'next/legacy/image'

const myLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

const MyImage = (props) => {
  return (
    <Image
      loader={myLoader}
      src="me.png"
      alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}

sizes

一個字串,提供有關圖片在不同斷點下寬度的資訊。sizes 的值會極大影響使用 layout="responsive"layout="fill" 的圖片效能。對於使用 layout="intrinsic"layout="fixed" 的圖片,此屬性會被忽略。

sizes 屬性在圖片效能方面有兩個重要作用:

首先,瀏覽器使用 sizes 的值來決定從 next/legacy/image 自動生成的來源集中下載哪個尺寸的圖片。當瀏覽器選擇時,它還不知道圖片在頁面上的實際大小,因此會選擇與視口相同或更大的圖片。sizes 屬性允許您告訴瀏覽器圖片實際上會比全螢幕小。如果不指定 sizes 值,則預設使用 100vw(全螢幕寬度)。

其次,sizes 值會被解析並用於修剪自動建立的來源集中的值。如果 sizes 屬性包含如 50vw 這樣的值(表示視口寬度的百分比),則來源集會被修剪,以排除任何可能永遠不需要的過小值。

例如,如果您知道您的樣式會導致圖片在行動裝置上全寬顯示,在平板電腦上以 2 欄佈局顯示,在桌面上以 3 欄佈局顯示,則應包含如下所示的 sizes 屬性:

import Image from 'next/legacy/image'
const Example = () => (
  <div className="grid-element">
    <Image
      src="/example.png"
      layout="fill"
      sizes="(max-width: 768px) 100vw,
              (max-width: 1200px) 50vw,
              33vw"
    />
  </div>
)

這個 sizes 範例可能會對效能指標產生顯著影響。如果沒有 33vw 的 sizes,從伺服器選擇的圖片寬度會是實際需要的 3 倍。由於檔案大小與寬度的平方成正比,沒有 sizes 時,使用者下載的圖片會比實際需要的大 9 倍。

了解更多關於 srcsetsizes

quality

最佳化圖片的品質,介於 1100 之間的整數,100 為最佳品質。預設為 75

priority

當設為 true 時,圖片將被視為高優先級並進行預載入。對於使用 priority 的圖片,延遲載入會自動停用。

您應該對檢測為最大內容繪製 (LCP) 元素的任何圖片使用 priority 屬性。根據不同視口大小,可能需要為多個圖片設定 priority。

僅當圖片在首屏可見時使用。預設為 false

placeholder

圖片載入時使用的佔位符。可能的值為 blurempty。預設為 empty

當設為 blur 時,將使用 blurDataURL 屬性作為佔位符。如果 src靜態匯入的物件且匯入的圖片是 .jpg.png.webp.avif,則 blurDataURL 會自動填充。

對於動態圖片,您必須提供 blurDataURL 屬性。像 Plaiceholder 這樣的解決方案可以幫助生成 base64

當設為 empty 時,圖片載入期間不會有佔位符,只有空白空間。

試試看:

進階屬性

在某些情況下,您可能需要更高級的使用方式。<Image /> 元件可選地接受以下進階屬性。

style

允許傳遞 CSS 樣式給底層的圖片元素。

請注意,所有 layout 模式都會對圖片元素應用自己的樣式,這些自動樣式優先於 style prop。

還要注意,必要的 widthheight props 可能會與您的樣式互動。如果您使用樣式修改圖片的 width,則必須同時設定 height="auto" 樣式,否則圖片會變形。

objectFit

定義當使用 layout="fill" 時,圖片如何適應其父容器。

此值傳遞給 src 圖片的 object-fit CSS 屬性

objectPosition

定義當使用 layout="fill" 時,圖片在其父元素中的定位方式。

此值傳遞給應用於圖片的 object-position CSS 屬性

onLoadingComplete

一個回調函式,在圖片完全載入且佔位符被移除後呼叫。

onLoadingComplete 函式接受一個參數,該參數是具有以下屬性的物件:

loading

圖片的載入行為。預設為 lazy

當設為 lazy 時,延遲載入圖片直到它到達與視口的計算距離。

當設為 eager 時,立即載入圖片。

了解更多

blurDataURL

一個資料 URL,在 src 圖片成功載入前用作佔位圖片。僅在與 placeholder="blur" 結合使用時生效。

必須是 base64 編碼的圖片。它會被放大和模糊處理,因此建議使用非常小的圖片(10px 或更小)。包含較大的圖片作為佔位符可能會損害應用程式效能。

試試看:

您也可以生成純色資料 URL 來匹配圖片。

lazyBoundary

一個字串(語法類似於 margin 屬性),用作檢測視口與圖片交集並觸發延遲載入的邊界框。預設為 "200px"

如果圖片嵌套在根文件以外的可滾動父元素中,您還需要指定 lazyRoot prop。

了解更多

lazyRoot

一個指向可滾動父元素的 React Ref。預設為 null(文件視口)。

Ref 必須指向 DOM 元素或將 Ref 轉發到底層 DOM 元素的 React 元件。

指向 DOM 元素的範例

import Image from 'next/legacy/image'
import React from 'react'

const Example = () => {
  const lazyRoot = React.useRef(null)

  return (
    <div ref={lazyRoot} style={{ overflowX: 'scroll', width: '500px' }}>
      <Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
      <Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
    </div>
  )
}

指向 React 元件的範例

import Image from 'next/legacy/image'
import React from 'react'

const Container = React.forwardRef((props, ref) => {
  return (
    <div ref={ref} style={{ overflowX: 'scroll', width: '500px' }}>
      {props.children}
    </div>
  )
})

const Example = () => {
  const lazyRoot = React.useRef(null)

  return (
    <Container ref={lazyRoot}>
      <Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
      <Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
    </Container>
  )
}

了解更多

unoptimized

當設定為 true 時,src 中的原始圖片將直接使用,不會改變品質、大小或格式。預設值為 false

這對於無法從優化中受益的圖片非常有用,例如小圖片(小於 1KB)、向量圖片(SVG)或動畫圖片(GIF)。

import Image from 'next/image'

const UnoptimizedImage = (props) => {
  return <Image {...props} unoptimized />
}

自 Next.js 12.3.0 起,可以透過更新 next.config.js 並加入以下配置,將此屬性套用至所有圖片:

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

其他屬性

<Image /> 元件的其他屬性將傳遞給底層的 img 元素,但以下屬性除外:

配置選項

遠端模式 (Remote Patterns)

為了保護您的應用程式免受惡意使用者攻擊,使用外部圖片時需要進行配置。這確保只有來自您帳戶的外部圖片可以透過 Next.js 圖片優化 API 提供。這些外部圖片可以在 next.config.js 檔案中使用 remotePatterns 屬性進行配置,如下所示:

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

須知:上述範例將確保 next/legacy/imagesrc 屬性必須以 https://example.com/account123/ 開頭,且不能有查詢字串。任何其他協定、主機名稱、連接埠或不匹配的路徑將回傳 400 Bad Request。

以下是 next.config.js 檔案中使用 hostname 萬用字元模式的 remotePatterns 屬性範例:

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

須知:上述範例將確保 next/legacy/imagesrc 屬性必須以 https://img1.example.comhttps://me.avatar.example.com 或任何數量的子網域開頭。它不能有連接埠或查詢字串。任何其他協定或不匹配的主機名稱將回傳 400 Bad Request。

萬用字元模式可用於 pathnamehostname,並具有以下語法:

  • * 匹配單一路徑段或子網域
  • ** 匹配任意數量的路徑段(在結尾)或子網域(在開頭)

** 語法不能在模式的中間使用。

須知:當省略 protocolportpathnamesearch 時,隱含使用萬用字元 **。這不建議使用,因為它可能允許惡意行為者優化您無意允許的 URL。

以下是 next.config.js 檔案中使用 searchremotePatterns 屬性範例:

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

須知:上述範例將確保 next/legacy/imagesrc 屬性必須以 https://assets.example.com 開頭,且必須具有確切的查詢字串 ?v=1727111025337。任何其他協定或查詢字串將回傳 400 Bad Request。

網域 (Domains)

警告:自 Next.js 14 起已棄用,轉而使用嚴格的 remotePatterns 以保護您的應用程式免受惡意使用者攻擊。僅在您擁有該網域提供的所有內容時才使用 domains

remotePatterns 類似,domains 配置可用於提供允許的外部圖片主機名稱列表。

然而,domains 配置不支援萬用字元模式匹配,也無法限制協定、連接埠或路徑名稱。

以下是 next.config.js 檔案中的 domains 屬性範例:

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

載入器配置 (Loader Configuration)

如果您想使用雲端供應商來優化圖片,而不是使用 Next.js 內建的圖片優化 API,您可以在 next.config.js 檔案中配置 loaderpath 前綴。這允許您為圖片的 src 使用相對 URL,並自動為您的供應商生成正確的絕對 URL。

next.config.js
module.exports = {
  images: {
    loader: 'imgix',
    path: 'https://example.com/myaccount/',
  },
}

內建載入器 (Built-in Loaders)

以下圖片優化雲端供應商已包含:

  • 預設:自動適用於 next devnext start 或自訂伺服器
  • Vercel:部署在 Vercel 時自動適用,無需配置。了解更多
  • Imgixloader: 'imgix'
  • Cloudinaryloader: 'cloudinary'
  • Akamailoader: 'akamai'
  • 自訂:loader: 'custom' 透過在 next/legacy/image 元件上實作 loader 屬性來使用自訂雲端供應商

如果您需要其他供應商,可以使用 next/legacy/imageloader 屬性。

使用 output: 'export' 時,圖片無法在構建時優化,僅能按需優化。要將 next/legacy/imageoutput: 'export' 一起使用,您需要使用非預設的載入器。在討論中了解更多。

進階

以下配置適用於進階使用情境,通常不需要。如果您選擇配置以下屬性,將覆蓋未來更新中 Next.js 預設的任何變更。

裝置尺寸 (Device Sizes)

如果您知道使用者的預期裝置寬度,可以在 next.config.js 中使用 deviceSizes 屬性指定裝置寬度斷點列表。當 next/legacy/image 元件使用 layout="responsive"layout="fill" 時,這些寬度用於確保為使用者的裝置提供正確的圖片。

如果未提供配置,則使用以下預設值。

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

圖片尺寸 (Image Sizes)

您可以在 next.config.js 檔案中使用 images.imageSizes 屬性指定圖片寬度列表。這些寬度與 裝置尺寸 (device sizes) 陣列連接,形成用於生成圖片 srcset 的完整尺寸陣列。

之所以有兩個獨立的列表,是因為 imageSizes 僅用於提供 sizes 屬性的圖片,這表示圖片的寬度小於螢幕的完整寬度。因此,imageSizes 中的尺寸都應小於 deviceSizes 中的最小尺寸。

如果未提供配置,則使用以下預設值。

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

可接受的格式 (Acceptable Formats)

預設的 圖片優化 API 會透過請求的 Accept 標頭自動檢測瀏覽器支援的圖片格式,以確定最佳輸出格式。

如果 Accept 標頭匹配多個配置的格式,則使用陣列中的第一個匹配項。因此,陣列順序很重要。如果沒有匹配項(或來源圖片是 動畫圖片),圖片優化 API 將回退到原始圖片的格式。

如果未提供配置,則使用以下預設值。

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

您可以啟用 AVIF 支援,如果瀏覽器 不支援 AVIF,則會回退到 src 圖片的原始格式:

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

須知

  • 我們仍然建議在大多數使用情境中使用 WebP。
  • AVIF 通常需要多 50% 的時間來編碼,但與 WebP 相比,壓縮率高出 20%。這意味著首次請求圖片時通常會較慢,但後續的快取請求會更快。
  • 如果您在 Next.js 前使用 Proxy/CDN 自託管,必須配置 Proxy 轉發 Accept 標頭。

快取行為 (Caching Behavior)

以下描述預設 載入器 (loader) 的快取演算法。對於所有其他載入器,請參考您的雲端供應商文件。

圖片在請求時動態優化,並儲存在 <distDir>/cache/images 目錄中。優化後的圖片檔案將用於後續請求,直到過期為止。當請求匹配到已快取但已過期的檔案時,會立即提供過期的圖片(稱為 stale)。然後在背景中重新優化圖片(也稱為重新驗證 (revalidation)),並使用新的過期日期儲存到快取中。

可以透過讀取 x-nextjs-cache(部署在 Vercel 時為 x-vercel-cache)回應標頭的值來確定圖片的快取狀態。可能的值如下:

  • MISS - 路徑不在快取中(最多發生一次,在首次訪問時)
  • STALE - 路徑在快取中,但已超過重新驗證時間,因此將在背景中更新
  • HIT - 路徑在快取中,且未超過重新驗證時間

過期時間(或稱最大壽命 (Max Age))由 minimumCacheTTL 配置或上游圖片的 Cache-Control 標頭中的較大者定義。具體來說,使用 Cache-Control 標頭的 max-age 值。如果同時找到 s-maxagemax-age,則優先使用 s-maxagemax-age 也會傳遞給任何下游客戶端,包括 CDN 和瀏覽器。

  • 您可以配置 minimumCacheTTL 以在上游圖片不包含 Cache-Control 標頭或值非常低時增加快取時間。
  • 您可以配置 deviceSizesimageSizes 以減少可能生成的圖片總數。
  • 您可以配置 格式 (formats) 以停用多種格式,僅使用單一圖片格式。

最小快取 TTL (Minimum Cache TTL)

您可以為快取的優化圖片配置存留時間 (TTL)(以秒為單位)。在許多情況下,最好使用 靜態圖片導入 (Static Image Import),它會自動對檔案內容進行雜湊處理,並使用 Cache-Control 標頭 immutable 永久快取圖片。

如果未提供配置,則使用以下預設值。

next.config.js
module.exports = {
  images: {
    minimumCacheTTL: 60, // 1 分鐘
  },
}

您可以增加 TTL 以減少重新驗證次數,並可能降低成本:

next.config.js
module.exports = {
  images: {
    minimumCacheTTL: 2678400, // 31 天
  },
}

優化圖片的過期時間(或稱最大壽命)由 minimumCacheTTL 或上游圖片的 Cache-Control 標頭中的較大者定義。

如果需要按圖片更改快取行為,可以配置 headers 在上游圖片(例如 /some-asset.jpg,而不是 /_next/image 本身)上設定 Cache-Control 標頭。

目前沒有機制可以手動使快取失效,因此最好保持 minimumCacheTTL 較低。否則,您可能需要手動更改 src 屬性或刪除 <distDir>/cache/images

停用靜態導入 (Disable Static Imports)

預設行為允許您導入靜態檔案,例如 import icon from './icon.png',然後將其傳遞給 src 屬性。

在某些情況下,如果與其他預期導入行為不同的插件衝突,您可能希望停用此功能。

您可以在 next.config.js 中停用靜態圖片導入:

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

危險允許 SVG (Dangerously Allow SVG)

預設的 載入器 (loader) 不會優化 SVG 圖片,原因有幾個。首先,SVG 是一種向量格式,意味著它可以無損縮放。其次,SVG 具有許多與 HTML/CSS 相同的功能,如果沒有適當的 內容安全政策 (Content Security Policy, CSP) 標頭,可能導致漏洞。

因此,我們建議在 src 屬性已知為 SVG 時使用 unoptimized 屬性。當 src".svg" 結尾時,這會自動發生。

但是,如果您需要使用預設的圖片優化 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

預設的 載入器 (loader)Content-Disposition 標頭設定為 attachment 以增加保護,因為 API 可以提供任意的遠端圖片。

預設值為 attachment,這會強制瀏覽器在直接訪問時下載圖片。這在 dangerouslyAllowSVGtrue 時尤其重要。

您可以選擇配置 inline 以允許瀏覽器在直接訪問時渲染圖片,而不是下載它。

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

動畫圖片 (Animated Images)

預設的 載入器 (loader) 會自動繞過動畫圖片的優化,並直接提供原始圖片。

對動畫檔案的自動檢測是盡力而為的,支援 GIF、APNG 和 WebP。如果您想明確繞過特定動畫圖片的優化,請使用 unoptimized 屬性。

版本歷史

版本變更
v13.0.0next/image 更名為 next/legacy/image