Astro has a well-earned reputation for performance. Static output, minimal JavaScript, built-in image optimization — for most of what affects page speed scores, Astro handles it well.
Image SEO is a different story. Fast delivery doesn’t mean your images rank. And Astro, like every other framework, leaves the actual image SEO work — file naming, alt text, schema markup — entirely up to you.
If you’re running a content site on Astro with EmDash as your CMS, there’s a cleaner way to handle this. Here’s what image SEO actually requires, why it’s usually skipped, and how to automate the whole workflow.
What Image SEO Actually Requires
Before getting into the tooling, it helps to be specific about what affects whether images appear in Google Image Search and in image carousels in regular search results.
File names matter more than most people think. Google uses the file name as one of the signals for what an image depicts. IMG_4821.jpg contributes nothing. golden-retriever-running-on-beach.webp tells the crawler what it’s looking at before it even processes the image. This is still underutilised — most CMS media uploads preserve the original camera or AI-generated filename.
Alt text is both an accessibility requirement and an SEO signal. The alt attribute is what Google reads when it can’t process the image itself. For AI-generated images, writing accurate alt text manually for every image is tedious enough that it usually doesn’t happen. For real photography, it’s often an afterthought.
WebP format is expected. Google’s PageSpeed Insights has flagged non-WebP images as an issue for years. Core Web Vitals scoring rewards smaller image payloads. If you’re serving PNG or JPEG where WebP is available, you’re leaving performance points on the table — and Google’s image index does factor in page experience signals.
ImageObject schema closes the loop. Structured data tells Google explicitly what an image is, who created it, what it depicts, and what page it belongs to. Most sites don’t have it. The ones that do see better image carousel inclusion and more confident indexing.
Getting all four right for every image — consistently, at scale — is where the workflow usually breaks down.
What Astro Handles Automatically
Astro’s built-in <Image /> component does a meaningful amount of work:
- Converts images to WebP at build time (for local assets)
- Generates
srcsetwith multiple size variants - Adds
widthandheightattributes to prevent layout shift - Lazy-loads images below the fold by default
For statically imported images in .astro files, this is largely automatic. The limitation is that it applies at build time, to images that exist in your project at build time. CMS-sourced images — uploaded through a media library, generated dynamically — go through a different path.
Astro’s image optimization doesn’t reach into your CMS. It doesn’t write alt text. It doesn’t generate schema. File naming is still whatever name the image had when it was uploaded.
The EmDash Media Library
EmDash is a headless CMS designed specifically for Astro and Cloudflare Workers. It runs server-side in your Cloudflare Worker — there’s no separate CMS infrastructure to manage.
EmDash has a media library that stores images in Cloudflare R2 (object storage) and tracks metadata — filename, mime type, alt text, dimensions — in a D1 database. When you reference an image in your content, you’re pulling from that library.
The media library is where image SEO metadata needs to live. If the library stores the correct filename, mime type, and alt text at upload time, every piece of content that references that image inherits correct SEO attributes automatically.
The gap is the upload workflow. Uploading an image through a standard CMS interface means you’re still manually naming it, manually writing alt text, and manually converting it to WebP if it came in as a PNG. Most of the time, at least one of those steps gets skipped.
The PixelSEO Plugin
The @pixelseo/emdash-plugin is an EmDash plugin that automates the full image SEO workflow for AI-generated images.
When you generate an image through the plugin:
- A text prompt goes to the pixelseo.ai API
- The API returns image bytes (PNG), a descriptive SEO-optimised filename, AI-generated alt text, and ImageObject schema
- The plugin converts the PNG to WebP using Cloudflare’s Images binding (at quality 80 — typically a 10x size reduction over PNG)
- The WebP bytes are uploaded to R2 with the correct content type
- A record is inserted into the EmDash media table with the filename, mime type, file size, and alt text
The result is an image in your media library that has the correct file name, the correct format, and alt text — already there when you pick it for a piece of content.
Installing the Plugin
npm install @pixelseo/emdash-plugin
Add it to your EmDash config:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import emdash from 'emdash/astro';
import { pixelseoPlugin } from '@pixelseo/emdash-plugin';
export default defineConfig({
integrations: [
emdash({
plugins: [pixelseoPlugin()],
}),
],
});
Add the Cloudflare Images binding to wrangler.jsonc for WebP conversion:
{
"images": {
"binding": "IMAGES"
}
}
Then go to Plugins → PixelSEO → Settings in your EmDash admin to enter your pixelseo.ai API key.
Getting a pixelseo.ai API Key
The plugin uses the pixelseo.ai API, which requires an account and credits:
- Create a free account at pixelseo.ai
- Purchase a credit pack at pixelseo.ai/pricing — each image generation costs 1 credit
- Create an API key in your dashboard and paste it into the plugin settings
What This Solves — and What It Doesn’t
The plugin handles AI-generated images well. For photography or externally sourced images uploaded manually, you still need to name files correctly before uploading and write alt text yourself. That’s a workflow problem rather than a tooling gap — the media library accepts whatever you give it.
For content sites where you want a consistent visual style with fresh images for each post, the AI generation workflow covers the full SEO checklist automatically. For sites that rely on real photography, the plugin is a useful addition but not a complete replacement for a naming and alt text process.
The ImageObject schema returned by the pixelseo.ai API is available in the generate response under seo.schema. Injecting that into your page is currently a manual step — the plugin stores the image in the media library, but wiring the schema into your Astro page template depends on how your content model is structured.
A Practical Checklist for Astro Image SEO
Whether you use the plugin or not, here’s what needs to be in place for images on an Astro site to perform well in search:
- File names describe the image content, include target keywords, use hyphens, no spaces
- Format is WebP for all photographic and AI-generated images
- Alt text is present on every
<img>tag, describes the image accurately, matches the page context - ImageObject schema is present on pages where images are a primary content element
- Dimensions are specified to prevent layout shift (Astro’s
<Image />handles this for local assets) - Lazy loading is applied to images below the fold (Astro defaults to this)
Astro covers the last two automatically. The first four require a deliberate workflow. The PixelSEO plugin automates the first three for AI-generated images — and that’s where most content sites leave the most ground on the table.