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:
- Perhaps
next/image
doesn't interact with the<picture>
tag exactly the same way as<img>
? But I'm not finding anything online about usingnext/image
with the<picture>
tag… - Perhaps I should be providing this media-query-dependant source set in a different way when using
next/image
? But, I'm not finding anymedia
attribute in thenext/image
docs…
Question:
How can I change the src
of my next/image
based on the user's preferred color scheme?
Non-solutions:
- I could put 2 images on the page and use
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. - I could change the
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. - I could use cookies to let the server know about a user's color scheme preference and render the page consequently, but this would not work for the very first visit and comes with the requirement to include a cookie bar to inform the user of the reasons behind the use of cookies, as well as a way to opt-out.