diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx
index 78e263d0aa5bb..a5bcceae4e636 100644
--- a/packages/next/client/image.tsx
+++ b/packages/next/client/image.tsx
@@ -245,6 +245,7 @@ function defaultImageLoader(loaderProps: ImageLoaderProps) {
function handleLoading(
img: HTMLImageElement | null,
src: string,
+ layout: LayoutValue,
placeholder: PlaceholderValue,
onLoadingComplete?: OnLoadingComplete
) {
@@ -267,6 +268,21 @@ function handleLoading(
// underlying DOM element because it could be misused.
onLoadingComplete({ naturalWidth, naturalHeight })
}
+ if (process.env.NODE_ENV !== 'production') {
+ const parentStyle = img.parentElement?.parentElement?.style
+ if (layout === 'responsive' && parentStyle?.display === 'flex') {
+ console.warn(
+ `Image with src "${src}" may not render properly as a child of a flex container. Consider wrapping the image with a div to configure the width.`
+ )
+ } else if (
+ layout === 'fill' &&
+ parentStyle?.position !== 'relative'
+ ) {
+ console.warn(
+ `Image with src "${src}" may not render properly with a parent using position:"${parentStyle?.position}". Consider changing the parent style to position:"relative" with a width and height.`
+ )
+ }
+ }
})
}
}
@@ -612,7 +628,7 @@ export default function Image({
className={className}
ref={(img) => {
setRef(img)
- handleLoading(img, srcString, placeholder, onLoadingComplete)
+ handleLoading(img, srcString, layout, placeholder, onLoadingComplete)
}}
style={{ ...imgStyle, ...blurStyle }}
/>
diff --git a/test/integration/image-component/default/pages/layout-fill-inside-nonrelative.js b/test/integration/image-component/default/pages/layout-fill-inside-nonrelative.js
new file mode 100644
index 0000000000000..bbcb08668695f
--- /dev/null
+++ b/test/integration/image-component/default/pages/layout-fill-inside-nonrelative.js
@@ -0,0 +1,13 @@
+import React from 'react'
+import Image from 'next/image'
+import img from '../public/test.jpg'
+
+const Page = () => {
+ return (
+
+
+
+ )
+}
+
+export default Page
diff --git a/test/integration/image-component/default/pages/layout-responsive-inside-flex.js b/test/integration/image-component/default/pages/layout-responsive-inside-flex.js
new file mode 100644
index 0000000000000..d6ab8d32debcb
--- /dev/null
+++ b/test/integration/image-component/default/pages/layout-responsive-inside-flex.js
@@ -0,0 +1,13 @@
+import React from 'react'
+import Image from 'next/image'
+import img from '../public/test.jpg'
+
+const Page = () => {
+ return (
+
+
+
+ )
+}
+
+export default Page
diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js
index aff13d076e6ff..6be77fdb6d20d 100644
--- a/test/integration/image-component/default/test/index.test.js
+++ b/test/integration/image-component/default/test/index.test.js
@@ -582,6 +582,33 @@ function runTests(mode) {
)
})
+ it('should warn when img with layout=responsive is inside flex container', async () => {
+ const browser = await webdriver(appPort, '/layout-responsive-inside-flex')
+
+ const warnings = (await browser.log('browser'))
+ .map((log) => log.message)
+ .join('\n')
+ expect(await hasRedbox(browser)).toBe(false)
+ expect(warnings).toMatch(
+ /Image with src (.*)jpg(.*) may not render properly as a child of a flex container. Consider wrapping the image with a div to configure the width/gm
+ )
+ })
+
+ it('should warn when img with layout=fill is inside a container without position relative', async () => {
+ const browser = await webdriver(
+ appPort,
+ '/layout-fill-inside-nonrelative'
+ )
+
+ const warnings = (await browser.log('browser'))
+ .map((log) => log.message)
+ .join('\n')
+ expect(await hasRedbox(browser)).toBe(false)
+ expect(warnings).toMatch(
+ /Image with src (.*)jpg(.*) may not render properly with a parent using position:\"static\". Consider changing the parent style to position:\"relative\"/gm
+ )
+ })
+
it('should warn when using a very small image with placeholder=blur', async () => {
const browser = await webdriver(appPort, '/small-img-import')