I have a hero with multiple images, I want to display images according to screen sizes, for example, if the user is using a big screen, the hero will load the large/wide images, and if he uses a phone, the hero will display a different image that is not wide to fit the screen. I do not know how to do this with nextjs, there is no way to specify which image to load on a different screen.
I did solve the problem using nextjs's useMediaQuery { const mobile = useMediaQuery(theme.breakpoints.down('sm')); }, but the results aren't perfect, because if you use mobile ? [....] : [....] you cannot add 'priority' to the image components, if you try to add it, it will load both images first, then execute the conditional statement to hide one. so you have to sacrifice that.
It's sad that this is not supported by next/image
. What we can do for now is to use the native picture
html element. Now that in NextJS 13 the Image component is not wrapped by any div
or span
wrapper anymore, we can now do the ff:
<div className="image-container">
<picture>
<source media="(max-width: 37.5em)" srcSet="mobile-img.jpg">
<source media="(min-width: 62em)" srcset="desktop-img.jpg">
<source media="(min-width: 37.5em)" srcset="tablet-img.jpg">
<Image src="desktop-img.jpg" alt="alt text here" fill />
</picture>
</div>
It seems like Image
doesn't support that use case. I found this and it works as expected. https://github.com/vercel/next.js/discussions/32196#discussioncomment-1761938
I had a similar issue but what I did was create a new next/image component right next to the original one, but with the additional attribute of
media="(min-width: 1440px)"
I dont know if this is a proper optimized solution, it might be a bit janky but it works for me. In my case I only have two images, where one is mobile/tablet and the other is for desktop.
edit: nevermind that did not work, coincidentally it appeared to work but it just hid the second image behind it. fixed it by giving new classes,and change display to none or block to hide and unhide it
@media (width<= 1439px) {
.image {
...
}
.image2 {
display: none
}
}
I used the useMediaQuery()
method from Material UI,
but it didn't seem SEO-friendly and was also a bit laggy
So this is a more straightforward, more responsive way of doing it
Also, this is the method used by most of the websites
import Image from "next/image"
export function DynamicImage({ src = "", mobileOnlySrc = "" }) {
return (
<div>
<Image src={src} fill className={`${(mobileOnlySrc !== "") ? 'hidden lg:block' : ''}`} />
{(mobileOnlySrc !== "") && (
<Image src={mobileOnlySrc} fill className={`${(mobileOnlySrc !== "") ? 'lg:hidden' : ''}`} />
)}
</div>
)
}
I think you probably want to control the width and height on the parent component, make it relative and the use the property fill={true}
on the Image component.
<div className="relative h-32 w-32">
<Image
src={"/default-profile-picture.png"}
fill={true}
alt="Profile picture"
/>
</div>
I did solve the problem using nextjs's useMediaQuery { const mobile = useMediaQuery(theme.breakpoints.down('sm')); }, but the results aren't perfect, because if you use mobile ? [....] : [....] you cannot add 'priority' to the image components, if you try to add it, it will load both images first, then execute the conditional statement to hide one. so you have to sacrifice that.
© 2022 - 2025 — McMap. All rights reserved.