How to change Next/Image according to screen size?
Asked Answered
M

6

10

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.

Mailand answered 19/11, 2022 at 1:13 Comment(0)
M
-1

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.

Mailand answered 22/11, 2022 at 13:35 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Tantalum
P
6

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>
Pigeon answered 18/6, 2023 at 20:0 Comment(1)
Just what I needed! :) +1Concrescence
I
3

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

Intertype answered 19/2, 2023 at 1:12 Comment(0)
C
0

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
   }
}
Cattleman answered 21/6, 2023 at 5:15 Comment(0)
S
0

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>
    )
}
Suitcase answered 21/10, 2023 at 13:41 Comment(0)
C
0

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>
Charmion answered 29/10, 2023 at 12:7 Comment(0)
M
-1

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.

Mailand answered 22/11, 2022 at 13:35 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Tantalum

© 2022 - 2025 — McMap. All rights reserved.