<Image>

範例

此 API 參考將幫助您了解如何使用圖片元件提供的 屬性 (props)配置選項。關於功能和用法,請參閱 圖片元件 頁面。

app/page.js
import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="作者的照片"
    />
  )
}

屬性

以下是圖片元件可用的屬性摘要:

屬性範例類型狀態
srcsrc="/profile.png"字串必填
widthwidth={500}整數 (px)必填
heightheight={500}整數 (px)必填
altalt="作者的照片"字串必填
loaderloader={imageLoader}函式-
fillfill={true}布林值-
sizessizes="(max-width: 768px) 100vw, 33vw"字串-
qualityquality={80}整數 (1-100)-
prioritypriority={true}布林值-
placeholderplaceholder="blur"字串-
stylestyle={{objectFit: "contain"}}物件-
onLoadingCompleteonLoadingComplete={img => done())}函式已棄用
onLoadonLoad={event => done())}函式-
onErroronError(event => fail()}函式-
loadingloading="lazy"字串-
blurDataURLblurDataURL="data:image/jpeg..."字串-
overrideSrcoverrideSrc="/seo.png"字串-

必填屬性

圖片元件需要以下屬性:srcwidthheightalt

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

必須是以下之一:

  • 靜態匯入 的圖片檔案
  • 路徑字串。可以是絕對外部 URL 或內部路徑,具體取決於 loader 屬性。

使用外部 URL 時,必須將其新增到 next.config.js 中的 remotePatterns

width

width 屬性代表 渲染 寬度(以像素為單位),因此會影響圖片顯示的大小。

必填,除非是 靜態匯入的圖片 或使用 fill 屬性 的圖片。

height

height 屬性代表 渲染 高度(以像素為單位),因此會影響圖片顯示的大小。

必填,除非是 靜態匯入的圖片 或使用 fill 屬性 的圖片。

alt

alt 屬性用於為螢幕閱讀器和搜尋引擎描述圖片。如果圖片被禁用或載入時發生錯誤,它也是替代文字。

它應包含可以替代圖片 而不改變頁面含義 的文字。它不是用來補充圖片的,也不應重複圖片上方或下方標題中已提供的資訊。

如果圖片是 純裝飾性不面向使用者alt 屬性應為空字串 (alt="")。

了解更多

可選屬性

<Image /> 元件接受許多超出必填屬性的附加屬性。本節描述圖片元件最常用的屬性。有關較少使用的屬性詳情,請參閱 進階屬性 部分。

loader

用於解析圖片 URL 的自訂函式。

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

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

'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="作者的照片"
      width={500}
      height={500}
    />
  )
}

須知:使用像 loader 這樣接受函式的屬性,需要使用 客戶端元件 (Client Components) 來序列化提供的函式。

或者,您可以在 next.config.js 中使用 loaderFile 配置來設定應用程式中所有 next/image 實例,而無需傳遞屬性。

fill

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

一個布林值,使圖片填滿父元素,這在 widthheight 未知時非常有用。

父元素 必須 設定 position: "relative"position: "fixed"position: "absolute" 樣式。

預設情況下,img 元素會自動被賦予 position: "absolute" 樣式。

如果沒有對圖片應用任何樣式,圖片將拉伸以適應容器。您可能更喜歡設定 object-fit: "contain" 以使圖片按比例縮放以適應容器並保持寬高比。

或者,object-fit: "cover" 將使圖片填滿整個容器並被裁剪以保持寬高比。為了看起來正確,應將 overflow: "hidden" 樣式賦予父元素。

更多資訊,請參閱:

sizes

一個類似媒體查詢的字串,提供有關圖片在不同斷點下寬度的資訊。sizes 的值將極大影響使用 fill設定為響應式大小 的圖片的效能。

sizes 屬性有兩個與圖片效能相關的重要用途:

  1. 首先,sizes 的值由瀏覽器用來決定從 next/image 自動生成的 srcset 中下載哪個尺寸的圖片。當瀏覽器選擇時,它還不知道圖片在頁面上的大小,因此它會選擇與視窗相同大小或更大的圖片。sizes 屬性允許您告訴瀏覽器圖片實際上會比全螢幕小。如果在具有 fill 屬性的圖片中未指定 sizes 值,則使用預設值 100vw(全螢幕寬度)。
  2. 其次,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}

優化圖片的品質,介於 1100 之間的整數,其中 100 是最高品質,因此檔案大小也最大。預設為 75

如果在 next.config.js 中定義了 qualities 配置,則 quality 屬性必須與配置中定義的值之一匹配。

須知:如果原始來源圖片品質已經很低,將 quality 屬性設定過高可能會導致優化後的圖片比原始來源圖片更大。

priority

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

當為 true 時,圖片將被視為高優先級並進行 預載 (preload)。對於使用 priority 的圖片,懶加載會自動禁用。

您應該在檢測為 最大內容繪製 (LCP) 元素的任何圖片上使用 priority 屬性。對於不同的視窗大小,不同的圖片可能是 LCP 元素,因此擁有多個優先級圖片可能是合適的。

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

placeholder

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

圖片載入時使用的佔位符。可能的值為 bluremptydata:image/...。預設為 empty

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

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

當為 data:image/... 時,將使用 Data URL 作為圖片載入時的佔位符。

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

試試看:

進階屬性

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

style

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

components/ProfileImage.js
const imageStyle = {
  borderRadius: '50%',
  border: '1px solid #fff',
}

export default function ProfileImage() {
  return <Image src="..." style={imageStyle} />
}

請記住,必填的 width 和 height 屬性可以與您的樣式互動。如果您使用樣式修改圖片的寬度,則應將其高度樣式設定為 auto 以保持其固有寬高比,否則圖片會變形。

onLoadingComplete

'use client'

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

警告:自 Next.js 14 起已棄用,建議改用 onLoad

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

回呼函式將使用一個參數呼叫,該參數是底層 <img> 元素的參考。

須知:使用像 onLoadingComplete 這樣接受函式的屬性,需要使用 客戶端元件 (Client Components) 來序列化提供的函式。

onLoad

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

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

回呼函式將使用一個參數呼叫,該參數是 Event,其 target 參考底層的 <img> 元素。

須知:使用像 onLoad 這樣接受函式的屬性,需要使用 客戶端元件 (Client Components) 來序列化提供的函式。

onError

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

一個回呼函式,在圖片載入失敗時呼叫。

須知:使用像 onError 這樣接受函式的屬性,需要使用 客戶端元件 (Client Components) 來序列化提供的函式。

loading

建議:此屬性僅適用於進階使用情境。將圖片切換為 eager 載入通常會影響效能。我們建議改用 priority 屬性,該屬性會主動預載圖片。

loading = 'lazy' // {lazy} | {eager}

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

當設定為 lazy 時,延遲載入圖片直到它進入與視窗的計算距離內。

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

了解更多關於 loading 屬性

blurDataURL

一個 Data URL,用於在 src 圖片成功載入前作為佔位圖片。僅在與 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 起,可以通過更新 next.config.js 來為所有圖片設定此屬性:

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

overrideSrc

當向 <Image> 組件提供 src 屬性時,會自動為生成的 <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 屬性來覆蓋它。

例如,當從 <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"
/>

decoding

向瀏覽器提示是否應等待圖片解碼後再呈現其他內容更新。預設為 async

可能的值如下:

  • async - 異步解碼圖片,允許其他內容在解碼完成前渲染。
  • sync - 同步解碼圖片,以便與其他內容一起原子性呈現。
  • auto - 對解碼模式無偏好;由瀏覽器決定最佳方式。

了解更多關於 decoding 屬性

其他屬性

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

配置選項

除了屬性外,你還可以在 next.config.js 中配置圖片組件。以下選項可用:

localPatterns

你可以選擇在 next.config.js 文件中配置 localPatterns,以允許優化特定路徑並阻止所有其他路徑。

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

須知:上面的例子將確保 next/imagesrc 屬性必須以 /assets/images/ 開頭且不能有查詢字串。嘗試優化任何其他路徑將返回 400 Bad Request。

remotePatterns

為了保護你的應用程序免受惡意用戶的侵害,需要使用外部圖片時必須進行配置。這確保只有來自你帳戶的外部圖片可以通過 Next.js 圖片優化 API 提供。這些外部圖片可以在 next.config.js 文件中通過 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。

以下是 next.config.js 文件中使用 hostname 通配符模式的 remotePatterns 屬性示例:

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

須知:上面的例子將確保 next/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/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'],
  },
}

loaderFile

如果你想使用雲端供應商來優化圖片,而不是使用 Next.js 內建的圖片優化 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 屬性 來配置每個 next/image 實例。

範例:

須知:自訂圖片載入器文件(接受一個函數)需要使用 客戶端組件 來序列化提供的函數。

進階

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

deviceSizes

如果你知道用戶的預期設備寬度,可以在 next.config.js 中使用 deviceSizes 屬性指定設備寬度斷點列表。當 next/image 組件使用 sizes 屬性時,這些寬度用於確保為用戶的設備提供正確的圖片。

如果未提供配置,則使用以下默認值。

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

imageSizes

你可以在 next.config.js 文件中使用 images.imageSizes 屬性指定圖片寬度列表。這些寬度與 裝置尺寸 數組合併,形成用於生成圖片 srcset 的完整尺寸數組。

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

如果未提供配置,則使用以下默認值。

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

qualities

默認的 圖片優化 API 將自動允許從 1 到 100 的所有品質。如果你想限制允許的品質,可以在 next.config.js 中添加配置。

next.config.js
module.exports = {
  images: {
    qualities: [25, 50, 75],
  },
}

在上面的例子中,只允許三種品質:25、50 和 75。如果 quality 屬性不匹配此數組中的值,圖片將返回 400 Bad Request。

formats

默認的 圖片優化 API 將通過請求的 Accept 標頭自動檢測瀏覽器支持的圖片格式。

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

如果未提供配置,則使用以下默認值。

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

你可以通過以下配置啟用 AVIF 支持。

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

須知

  • AVIF 通常比 WebP 多花 20% 的時間編碼,但壓縮率比 WebP 小 20%。這意味著第一次請求圖片時通常會較慢,然後後續緩存的請求會更快。
  • 如果你在 Next.js 前使用 Proxy/CDN 自託管,則必須配置 Proxy 轉發 Accept 標頭。

緩存行為

以下描述了默認 載入器 的緩存算法。對於所有其他載入器,請參考你的雲端供應商文檔。

圖片在請求時動態優化並存儲在 <distDir>/cache/images 目錄中。優化的圖片文件將用於後續請求,直到過期。當請求匹配緩存但已過期的文件時,立即提供過期的圖片。然後在後台重新優化圖片(也稱為重新驗證)並將新圖片保存到緩存中,帶有新的過期日期。

可以通過讀取 x-nextjs-cache 響應標頭的值來確定圖片的緩存狀態。可能的值如下:

  • MISS - 路徑不在緩存中(最多發生一次,在第一次訪問時)
  • STALE - 路徑在緩存中但超過了重新驗證時間,因此將在後台更新
  • HIT - 路徑在緩存中且未超過重新驗證時間

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

  • 當上游圖片不包含 Cache-Control 標頭或值非常低時,你可以配置 minimumCacheTTL 來增加緩存時間。
  • 你可以配置 deviceSizesimageSizes 來減少可能生成的圖片總數。
  • 你可以配置 格式 來禁用多種格式,轉而使用單一圖片格式。

minimumCacheTTL

你可以配置緩存優化圖片的生存時間(TTL,以秒為單位)。在許多情況下,最好使用 靜態圖片導入,它會自動哈希文件內容並使用 Cache-Control 標頭 immutable 永久緩存圖片。

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

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

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

目前沒有機制可以使緩存失效,因此最好將 minimumCacheTTL 設為較低的值。否則你可能需要手動更改 src 屬性或刪除 <distDir>/cache/images

disableStaticImages

默認行為允許你導入靜態文件,例如 import icon from './icon.png',然後將其傳遞給 src 屬性。

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

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

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

dangerouslyAllowSVG

預設的 loader 不會對 SVG 圖片進行最佳化,原因如下:首先,SVG 是一種向量格式,意味著它可以無損縮放。其次,SVG 具有許多與 HTML/CSS 相同的功能,若沒有適當的 內容安全政策 (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 以防止嵌入在圖片中的腳本執行。

動態圖片

預設的 loader 會自動跳過動態圖片的圖片最佳化,並直接提供原始圖片。

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

響應式圖片

預設生成的 srcset 包含 1x2x 圖片,以支援不同的裝置像素密度。然而,您可能希望渲染一個能隨視窗拉伸的響應式圖片。在這種情況下,您需要設定 sizes 以及 style(或 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 屬性並在父元素上設定 position: relative。根據所需的拉伸或裁剪行為,可以選擇設定 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;
  }
}
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} />
    </>
  )
}

須知loading="lazy" 的預設行為確保僅加載正確的圖片。您不能使用 priorityloading="eager",因為這會導致兩張圖片都加載。相反,您可以使用 fetchPriority="high"

試試看:

getImageProps

對於更高級的使用場景,您可以調用 getImageProps() 來獲取將傳遞給底層 <img> 元素的屬性,並將它們傳遞給另一個組件、樣式、畫布等。

這也避免了調用 React 的 useState(),因此可以提高性能,但不能與 placeholder 屬性一起使用,因為佔位圖將永遠不會被移除。

主題檢測 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() 提供不同的 srcwidthheightquality 屬性。

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 字符串轉換為 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>
  )
}

已知瀏覽器問題

這個 next/image 組件使用瀏覽器原生的 延遲加載,對於 Safari 15.4 之前的舊版瀏覽器可能會回退到立即加載。當使用模糊佔位圖時,Safari 12 之前的舊版瀏覽器會回退到空佔位圖。當使用 width/heightauto 的樣式時,可能會在 Safari 15 之前不 保留寬高比 的舊版瀏覽器上導致 版面偏移 (Layout Shift)。更多細節,請參閱 此 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+ 在加載時顯示白色背景。可能的解決方案:

版本歷史

版本變更內容
v14.2.23新增 qualities 配置。
v14.2.15新增 decoding 屬性及 localPatterns 配置。
v14.2.14新增 remotePatterns.search 屬性。
v14.2.0新增 overrideSrc 屬性。
v14.1.0getImageProps() 進入穩定版。
v14.0.0棄用 onLoadingComplete 屬性及 domains 配置。
v13.4.14placeholder 屬性支援 data:/image... 格式。
v13.2.0新增 contentDispositionType 配置。
v13.0.6新增 ref 屬性。
v13.0.0next/image 導入名稱變更為 next/legacy/imagenext/future/image 導入名稱變更為 next/image。提供 自動重構工具 可安全自動重命名導入。移除 <span> 包裹層。移除 layoutobjectFitobjectPositionlazyBoundarylazyRoot 屬性。alt 成為必填屬性。onLoadingComplete 接收 img 元素參照。移除內建載入器配置。
v12.3.0remotePatternsunoptimized 配置進入穩定版。
v12.2.0新增實驗性 remotePatterns 和實驗性 unoptimized 配置。移除 layout="raw"
v12.1.1新增 style 屬性。新增實驗性支援 layout="raw"
v12.1.0新增 dangerouslyAllowSVGcontentSecurityPolicy 配置。
v12.0.9新增 lazyRoot 屬性。
v12.0.0新增 formats 配置。
新增 AVIF 支援。
包裹層從 <div> 改為 <span>
v11.1.0新增 onLoadingCompletelazyBoundary 屬性。
v11.0.0src 屬性支援靜態導入。
新增 placeholder 屬性。
新增 blurDataURL 屬性。
v10.0.5新增 loader 屬性。
v10.0.1新增 layout 屬性。
v10.0.0引入 next/image