I am using the following code to show an image:
import Image from 'next/image'
// ...
<Image src={ausrufezeichen} alt="Ausrufezeichen"/>
The following HTML Code is being rendered:
<div style="display:inline-block;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;margin:0">
<div style="box-sizing:border-box;display:block;max-width:100%">
<img style="max-width:100%;display:block;margin:0;border:none;padding:0" alt="" aria-hidden="true" role="presentation" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjciIGhlaWdodD0iMjAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIvPg=="/>
</div>
<noscript>
<img alt="Ausrufezeichen" srcSet="/_next/image?url=%2F_next%2Fstatic%2Fimage%2Fpublic%2Fimg%2Fpfeile_punkte%2Ficon_ausrufezeichen.d442fe0f12568980c7889dc07a018b24.png&w=96&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fimage%2Fpublic%2Fimg%2Fpfeile_punkte%2Ficon_ausrufezeichen.d442fe0f12568980c7889dc07a018b24.png&w=256&q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fimage%2Fpublic%2Fimg%2Fpfeile_punkte%2Ficon_ausrufezeichen.d442fe0f12568980c7889dc07a018b24.png&w=256&q=75" decoding="async" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/>
</noscript>
<img alt="Ausrufezeichen" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/>
</div>
When I just checked my SEO status with 'SEO Minion', I noticed that I am shown a lot of images without alt-tag. Why is this first img displayed without alt tag? Can I add one there somehow?
There are a few things that you need to understand in your generated code:
<div style="display:inline-block;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;margin:0">
<div style="box-sizing:border-box;display:block;max-width:100%">
<img style="max-width:100%;display:block;margin:0;border:none;padding:0" alt="" aria-hidden="true" role="presentation" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjciIGhlaWdodD0iMjAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIvPg=="/>
</div>
<noscript>
<img alt="Ausrufezeichen" srcSet="/_next/image?url=%2F_next%2Fstatic%2Fimage%2Fpublic%2Fimg%2Fpfeile_punkte%2Ficon_ausrufezeichen.d442fe0f12568980c7889dc07a018b24.png&w=96&q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fimage%2Fpublic%2Fimg%2Fpfeile_punkte%2Ficon_ausrufezeichen.d442fe0f12568980c7889dc07a018b24.png&w=256&q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fimage%2Fpublic%2Fimg%2Fpfeile_punkte%2Ficon_ausrufezeichen.d442fe0f12568980c7889dc07a018b24.png&w=256&q=75" decoding="async" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/>
</noscript>
<img alt="Ausrufezeichen" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/>
</div>
First Image: It is a placeholder present there to prevent CLS. It will decode to a SVG image with width
and height
same as your image. Once your image is loaded, it will be removed from DOM.
Second Image: This one is your image but it is visible only if a user/browser has disabled JavaScript execution for your site or doesn't supports it. Also, it has a perfectly fine alt
tag.
Third Image: This is going to be your rendered image in a browser that has JS enabled. It is currently a 1x1 GIF, but scripts will change its source to load it (when user is about to view it, i.e. image is near the visible page).
Why you don't need to add (and shouldn't add) an alt
attribute other than ""
to placeholders:
The image source is inline and is nearly guaranteed to load properly.
Screen readers (or any other assistive technology) won't read it because it has alt=""
, aria-hidden="true"
and role="presentation"
.
A non-empty value of alt
attribute for these types of images would add audible clutter to screen reader output, and could distract users if the topic is different from that in adjacent text.
In these cases, a null (empty)
alt
text should be provided (alt=""
) so that they can be ignored by assistive technologies, such as screen readers. Text values for these types of images would add audible clutter to screen reader output or could distract users if the topic is different from that in adjacent text.
Screen readers also allow the use of WAI-ARIA to hide elements by using
role="presentation"
. However, currently, this feature is not as widely supported as using a nullalt
attribute.
Adding
aria-hidden="true"
to an element removes that element and all of its children from the accessibility tree. This can improve the experience for assistive technology users by hiding:
- purely decorative content, such as icons or images
- duplicated content, such as repeated text
- offscreen or collapsed content, such as menus
"Why is this first img
displayed without alt
attribute?"
It has alt=""
, and the placeholder thing I have covered above.
"Can I add one there somehow?"
You can do pretty-much anything by writing your own script(s). Here you need to search for such elements, and add alt
texts correspondingly.
But Next.js doesn't provides anything like that for perfectly valid reasons. Also, it won't appear on your page source. Your SEO profiler is probably checking the page source only, as once an image is rendered, the placeholder is removed from the DOM. My advice here is stop checking your web app on such things (ones that are not compatible with React).
Every big search engine Google (at least) knows how to let your page render before crawling. Moreover, an image with empty alt
attribute is not same as one without an alt
attribute.
For accessibility related stuff, try checking your page on web.dev/measure, PageSpeed Insights, or on your local machine using Lighthouse or Firefox Dev Tools' Accessibility Inspector.