Guides/Image SEO: Alt Text, Formats, Lazy-Loading and Sitemaps
Guide

Image SEO: A Technical Guide to Alt Text, Formats and Loading

Image SEO comes down to six things Google reads from your HTML: descriptive alt text, real filenames, next-gen formats, correct lazy-loading, dimensions, and image sitemaps.

Image SEO reduces to six things Google reads straight from your HTML and headers: descriptive alt text, a real filename, a modern format, the right loading behaviour, declared dimensions, and inclusion in a sitemap. None of these require JavaScript to detect, and five of the six are attributes on the <img> tag itself. Get them right and your images become eligible for image search, contribute to rich results, and stop dragging down Core Web Vitals.

Alt text: describe, do not stuff

Google uses the alt attribute to understand what an image depicts, for both web search and Google Images. The guidance is specific: write descriptive, context-relevant text, not a keyword list.

<img src="dalmatian-puppy-fetch.jpg" alt="Dalmatian puppy playing fetch in a park">
<!-- not: alt="puppy dog baby dog pup pups fetch park dog" -->

There are two distinct failure modes, and they are not the same:

Do not pad alt text to game rankings. Overlong, stuffed alt text is a weaker signal than a short, accurate one, and Crawlinx flags descriptions that run past a sensible length as images.alt_too_long. A screen reader and Googlebot both read the alt attribute, so writing for one serves the other.

Filenames are still a ranking signal

Google uses the image filename as one of the signals for image search. This is unusual — most on-page micro-signals have faded — but Google's own documentation still cites puppy.jpg as better than IMG00023.jpg. The filename is readable from the src attribute without ever fetching the image, so it costs nothing to get right at export time.

Use short, hyphen-separated, descriptive names: black-kitten-sleeping.jpg, not DSC_0428.JPG or image1.png. Reference the same image with the same URL consistently across the site, and place each image near the text it relates to so Google can associate the two.

Next-gen formats with fallbacks

WebP and AVIF are Google's recommended formats for performance; JPEG and PNG are legacy. AVIF generally compresses smaller than WebP, and WebP smaller than JPEG at equivalent quality, which directly helps Largest Contentful Paint on image-heavy pages.

Serve modern formats with a fallback so older clients still get a working image. The <picture> element does this cleanly:

<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="City skyline at dusk" width="1600" height="900">
</picture>

The browser picks the first format it supports; the <img> inside is the universal fallback and is where your alt, width, and height belong. Note that Google does not index CSS background-image — anything you want in image search must be a real <img> (or <picture>) in the markup.

Lazy-loading: never on the LCP image

loading="lazy" defers off-screen images until the user scrolls near them, which is correct for images below the fold. Google supports the attribute and recommends it — with one hard exception it states explicitly: do not lazy-load an image that is a candidate for Largest Contentful Paint.

The hero image, or any large above-the-fold image, is frequently the LCP element. Marking it loading="lazy" forces the browser to wait before fetching the single most important pixel on the page, which pushes LCP past the 2.5-second "good" threshold. This is one of the most common Core Web Vitals mistakes on modern sites.

The correct treatment for the LCP image is the opposite of lazy: load it eagerly and hint its priority.

<!-- Below the fold: lazy is right -->
<img src="gallery-12.webp" alt="…" loading="lazy" width="800" height="600">

<!-- The hero / LCP image: never lazy -->
<img src="hero.webp" alt="…" fetchpriority="high" width="1600" height="900">

fetchpriority="high" tells the browser to fetch the hero ahead of lower-priority resources. In frameworks this is often abstracted — Next.js next/image lazy-loads by default and exposes a priority prop that sets eager loading plus fetchpriority="high" for exactly this case. The rule to remember: lazy-load everything below the fold, load the LCP image eagerly with high priority. The performance mechanics are in our Core Web Vitals guide.

Dimensions prevent layout shift

An <img> without width and height gives the browser no idea how much space to reserve, so surrounding content jumps when the image finally loads. That jump is Cumulative Layout Shift, the third Core Web Vital. Declaring the intrinsic width and height (or a CSS aspect-ratio) lets the browser hold the space before the bytes arrive.

<img src="chart.webp" alt="Revenue by quarter" width="1200" height="675">

This is independent of, and complementary to, the lazy-loading rule — one prevents layout shift, the other governs load timing. Crawlinx flags images without declared dimensions as images.missing_dimensions, and images that return a non-200 or fail to load as images.broken.

Structured data and og:image

Images referenced in structured data have a higher chance of appearing in rich results. Article, Recipe, and Product markup all expect an image property, and Google requires those image URLs to be crawlable and indexable — never block them in robots.txt or serve them behind login. Signal the page's primary image with schema and with an Open Graph og:image for the social and link-preview surface. Getting the markup right is covered in our structured data guide.

Image sitemaps: only two tags survive

Google still recommends listing important images in a sitemap, either as a dedicated image sitemap or via the <image:image> extension on your existing URL entries. But the image sitemap namespace was cut down: image:caption, image:title, image:license, and image:geo_location are all deprecated. Only two tags remain in use:

<url>
  <loc>https://example.com/products/tent</loc>
  <image:image>
    <image:loc>https://example.com/img/tent-4-person.webp</image:loc>
  </image:image>
</url>

Do not spend effort populating the removed fields — Google ignores them. Declare the xmlns:image namespace, list <image:image> with an <image:loc> per image (up to 1,000 images per page URL), and put your descriptive metadata where Google actually reads it: the alt text and the surrounding page content. How sitemaps are declared and submitted is covered in the XML sitemaps guide.

How Crawlinx detects image problems

Crawlinx parses every <img> during the crawl and checks it against these rules without fetching image bytes where the signal is in the HTML: missing alt text (images.missing_alt), overlong stuffed alt (images.alt_too_long), absent dimensions that risk layout shift (images.missing_dimensions), and images that fail to load (images.broken). Run these alongside the technical SEO audit checklist so image issues surface next to the crawl, index, and performance checks they interact with.

Takeaway

Image SEO is mostly attribute hygiene on the <img> tag. Write descriptive alt text and mark decorative images with alt=""; keep real, hyphenated filenames; serve WebP or AVIF with a <picture> fallback; declare width and height to stop layout shift; never lazy-load the LCP image and give it fetchpriority="high" instead; and list images in a sitemap using the only two tags Google still reads, image:image and image:loc.

Related
Core Web Vitals: LCP, INP and CLS Explained (2026) Structured Data & Schema Markup Guide (2026) XML Sitemap Guide: Format, Limits and Common Mistakes Technical SEO Audit Checklist images.missing_alt images.alt_too_long images.missing_dimensions images.broken

Audit your own site — free

77 checks, internal PageRank, render-diff. No signup, results in ~30s.

Scan your site →