Static Site Image Optimization SEO Checklist (WebP, Dimensions, Alt Text)
Cut image payload 78% on a 120-post Hugo blog. Checklist covers build-time conversion, srcset, and alt text patterns that rank.
Site: 120 tutorial posts, ~8 images each, Hugo static export. Before: 4.2GB deploy, image SEO warnings in Ahrefs, image search traffic near zero. After: 940MB deploy, 340% increase in Google Image clicks over 90 days.
Checklist overview
□ Convert to WebP/AVIF at build time
□ Explicit width + height on every <img>
□ srcset for responsive sizes
□ Descriptive alt (not keyword stuffing)
□ Filename: post-topic-step-2.webp
□ Lazy load below fold only
□ Image sitemap or indexable /images/ paths
Build-time conversion (Hugo Pipes)
{{- $img := resources.Get .Destination -}}
{{- $sizes := slice 400 800 1200 -}}
{{- $srcset := slice -}}
{{- range $sizes -}}
{{- $resized := $img.Resize (printf "%dx webp q80" .) -}}
{{- $srcset = $srcset | append (printf "%s %dw" $resized.RelPermalink .) -}}
{{- end -}}
<img src="{{ ($img.Resize "800x webp q80").RelPermalink }}"
srcset="{{ delimit $srcset ", " }}"
sizes="(max-width: 600px) 100vw, 800px"
alt="{{ .Text }}" width="800" height="{{ div (mul 800 $img.Height) $img.Width }}"
loading="lazy" decoding="async">
Render hook: layouts/_default/_markup/render-image.html
Astro equivalent
import { Image } from 'astro:assets';
<Image src={import('./screenshot.png')} alt="VS Code terminal showing build output"
widths={[400, 800, 1200]} formats={['webp', 'avif']} loading="lazy" />
Alt text formula that ranks
Bad: alt="seo image optimization webp"
Good: alt="Lighthouse performance panel showing LCP improved from 3.2s to 1.0s after WebP conversion"
Pattern: [What it shows] + [context from surrounding heading]
Filename matters
Rename before commit:
IMG_2847.png → hugo-webp-render-hook-output.webp
screenshot.png → astro-image-component-srcset-example.webp
Google Image uses filename + alt + page context.
OG / Twitter images (separate from content images)
1200×630 WebP, < 200KB. Don't reuse tiny thumbnails — social previews affect CTR which affects rankings indirectly.
Image sitemap
<url>
<loc>https://example.com/posts/image-seo/</loc>
<image:image>
<image:loc>https://example.com/images/hugo-webp-render-hook-output.webp</image:loc>
<image:title>Hugo WebP render hook output</image:title>
</image:image>
</url>
Hugo: custom sitemap template. Astro: @astrojs/sitemap with image plugin.
Common errors
| Error | Fix |
|---|---|
resources.Get: resource not found | Move from static/ to assets/ |
| Blurry on retina | Add 2x size in srcset (1600w for 800px display) |
| LCP regression | First image: loading="eager" + preload |
| CLS from missing dimensions | Always output width/height attributes |
Audit script
# Find images missing alt in built HTML
grep -r '<img' public/ | grep -v 'alt=' | head
# Find oversized images
find public -name '*.png' -size +200k -exec ls -lh {} \;
Results
Total image weight: 4.2GB → 940MB (-78%)
LCP p75: 2.8s → 1.2s
Google Image clicks: 42/mo → 185/mo
Ahrefs image SEO issues: 890 → 12
Image SEO is boring work. It's also the highest ROI fix on tutorial blogs.