diff --git a/packages/next/src/client/image.tsx b/packages/next/src/client/image.tsx index d830fef14ec50..5e13f317f34ae 100644 --- a/packages/next/src/client/image.tsx +++ b/packages/next/src/client/image.tsx @@ -8,6 +8,7 @@ import React, { useMemo, useState, forwardRef, + version, } from 'react' import Head from '../shared/lib/head' import { getImageBlurSvg } from '../shared/lib/image-blur-svg' @@ -367,6 +368,23 @@ function handleLoading( }) } +function getDynamicProps( + fetchPriority?: string +): Record { + const [majorStr, minorStr] = version.split('.') + const major = parseInt(majorStr, 10) + const minor = parseInt(minorStr, 10) + if (major > 18 || (major === 18 && minor >= 3)) { + // In React 18.3.0 or newer, we must use camelCase + // prop to avoid "Warning: Invalid DOM property". + // See https://github.com/facebook/react/pull/25927 + return { fetchPriority } + } + // In React 18.2.0 or older, we must use lowercase prop + // to avoid "Warning: Invalid DOM property". + return { fetchpriority: fetchPriority } +} + const ImageElement = forwardRef( ( { @@ -401,10 +419,9 @@ const ImageElement = forwardRef( <> ( imageSrcSet={imgAttributes.srcSet} imageSizes={imgAttributes.sizes} crossOrigin={rest.crossOrigin} - // Keep lowercase until https://github.com/facebook/react/pull/25927 lands - fetchpriority={fetchPriority} + {...getDynamicProps(fetchPriority)} /> ) : null} diff --git a/test/integration/next-image-new/default/pages/priority.js b/test/integration/next-image-new/default/pages/priority.js index 3cc02b89bcbfc..57f025fe815a1 100644 --- a/test/integration/next-image-new/default/pages/priority.js +++ b/test/integration/next-image-new/default/pages/priority.js @@ -8,6 +8,7 @@ const Page = () => { basic-image { basic-image-crossorigin { load-eager { responsive1 { responsive2 { />