I'm trying to use a next/image
instead of a regular img
tag in the code below. With the regular <img>
tag, the following achieves exactly what I'm looking for:
<div>
<picture>
<source
srcSet="https://via.placeholder.com/100/333333/ffffff.png"
media="(prefers-color-scheme: dark)"
/>
<img
src='https://via.placeholder.com/100/dddddd/000000.png'
width='100px'
height='100px'
alt='Placeholder image'
/>
</picture>
<p>Change your OS or browser's preferred color scheme to see a different image.</p>
</div>
Indeed, when I set my OS (or browser) to the dark theme, I get a dark image, and vice-versa for the light theme.
However, if I try the same thing with a next/image
, I just get the light-themed image every time… I can't put this into a snippet because next/image
requires a Next.js server, but here is the code that I'm using, which, in my tests, is backed by a Next.js development server with the appropriate image-related settings configured in next.config.js:
// pages/test.js
import Image from 'next/image'
export default function MyWebPage () {
return (
<div>
<picture>
<source
srcSet="https://via.placeholder.com/100/333333/ffffff.png"
media="(prefers-color-scheme: dark)"
/>
<Image src='https://via.placeholder.com/100/dddddd/000000.png' width='100px' height='100px' alt='Placeholder image' />
</picture>
<p>You can change your OS or browser's preferred color scheme, but you'll always see the light-theme image.</p>
</div>
)
}
Here I never get the dark-themed image, unfortunately.
Theories:
next/image
doesn't interact with the <picture>
tag exactly the same way as <img>
? But I'm not finding anything online about using next/image
with the <picture>
tag…next/image
? But, I'm not finding any media
attribute in the next/image
docs…Question:
How can I change the src
of my next/image
based on the user's preferred color scheme?
Non-solutions:
display: none
on one of the two as a function of the user's preferred color scheme, but I'm hoping to find a solution that doesn't require so many duplicate images all over the place, which incurs a (small) performance penalty and makes the code that much harder to maintain, or that much more complex if a helper component is created.src
using Javascript when the page loads, but this would result in a flash of incorrectly styled content and generally does against my objective of having my page fully server-rendered and compatible with browsers where Javascript is turned off.A bit late to the party, but had no issues using this within NextJs 13.
// Relative import to your image file
import MyLightImage from '../../../public/my-light-image.png';
import MyDarkImage from '../../../public/my-dark-image.png';
const MyImage = () => {
return (
<picture>
<source srcSet={MyDarkImage.src} media="(prefers-color-scheme: dark)" />
<Image
src={MyLightImage}
alt="My image"
width={300}
height={300}
/>
</picture>
);
};
export default MyImage;
This would display MyImage
for light theme and MyDarkImage
for dark theme.