Joomla images and SEO: alt text, lazy loading and LCP
Fill Joomla's alt text field or tick No Description, pick images with the media field so lazy loading works, and load the first image eagerly.
Joomla does more for your images than most people realise. It writes width and height attributes, it adds loading="lazy", and it has a separate alt text field for every intro and full article image. It also does all of that only under certain conditions, and one of its defaults works against you on the most important image of the page.
The alt text field, and the checkbox next to it
Open an article and go to the Images and Links tab. Both the Intro Image and the Full Article Image have an Image Description (Alt Text) field and a No Description checkbox below it. The combination decides what ends up in the HTML:
- Alt text filled in: you get
alt="your text". This is what Google Images and screen readers use. - Field empty, No Description ticked: you get
alt="". That tells assistive software the image is decoration and can be skipped. Correct for a pattern or a mood photo that adds nothing to the text. - Field empty, box not ticked: Joomla leaves the alt attribute out entirely. Accessibility checkers and Lighthouse flag this as an error, and it is the state most older articles are in.
The same two fields appear when you insert an image into the editor with the media button, so images inside the article body follow the same rule.
What to write in it
Describe what the image shows in the context of the article, in one plain sentence. "Article Manager with the Batch button highlighted" helps a reader and a search engine. "Joomla SEO image best Joomla tips" helps neither and reads as keyword stuffing. The title attribute is not a replacement: search engines give it little weight and screen readers often ignore it.
Where Joomla's lazy loading comes from
When you pick an image with the media field, Joomla stores more than the path. The value looks like this:
images/blog/printer.jpg#joomlaImage://local-images/blog/printer.jpg?width=1280&height=960
The part after the # carries the real dimensions. The intro and full image layouts read them, write width and height on the <img> tag and add loading="lazy". The editor's media dialog does the same for body images and has an Image Lazyloading option that is on by default.
The catch: an image path typed by hand, pasted from another site or imported from an old Joomla 3 site has no #joomlaImage part. Those images get no width, no height and no lazy loading, which means the layout shifts while they load. Re-selecting the image once in the media field fixes the article. Batch-importing content is where this usually goes wrong, so check a few imported articles in the page source.
The image you should not lazy-load
Lazy loading is right for images further down the page. It is wrong for the image a visitor sees first, which on a blog page is the intro image of the first article and on an article page is usually the full article image. That image is often the Largest Contentful Paint element, and telling the browser to wait with it makes LCP worse. Lighthouse reports it as "Largest Contentful Paint image was lazily loaded".
Joomla cannot know which image is on top, so it lazy-loads all of them. You fix that with a layout override, the same way as any other template override.
The override
Copy layouts/joomla/content/intro_image.php to templates/your-template/html/layouts/joomla/content/intro_image.php (in a child template, put it in the child). Find the line that builds the image with HTMLHelper::_('image', ...) and add this directly above it:
static $drjCount = 0;
$drjCount++;
if ($drjCount === 1) {
$layoutAttr['loading'] = 'eager';
$layoutAttr['fetchpriority'] = 'high';
}
The static counter survives between calls during one page request, so only the first intro image on the page loads eagerly with high priority. The rest stay lazy. Do the same in full_image.php without the counter, because a single article has only one full image and it sits at the top.
Check the result in the page source rather than in the editor: the first <img> in the blog should now have fetchpriority="high" and no loading="lazy".
File size still matters most
None of this helps if the intro image is a 5 MB camera file. Resize and compress before upload, as described in what to do with an image before you upload it, and give the file a descriptive name while you are at it. joomla-batch-button.jpg tells a search engine something. IMG_4471.jpg does not, and Joomla keeps whatever name you upload.
A quick audit
- Open a blog page, view the source and search for
<img. Every tag should have an alt attribute, a width and a height. - Run Lighthouse on the same page. Look for "Image elements do not have [alt] attributes" and the lazily loaded LCP warning.
- For articles with a missing alt, fill the field or tick No Description. Batch processing does not cover image fields, so this is one article at a time; start with the ones that get traffic.
Doctor Joomla is a project of Cloudfaction, a Dutch agency building and maintaining Joomla sites since 1999. The articles are made with the help of AI, so tell us if something does not match your screen. Mail info@cloudfaction.nl if you want someone to look at yours.