Cookie Consent by Free Privacy Policy Generator

Cloudflare Workers script to populate missing alt image tags

I put this together while prepping for my BrightonSEO 2025 presentation but ended up leaving it out of the final deck. It’s a lightweight Cloudflare Workers script that does one thing well: it checks your HTML on the edge and fills in missing alt text on image tags using the image’s filename.

If the image already has an alt, it’s left alone. If it’s missing or empty, the script grabs the filename from the src, strips the extension, tidies it up (replaces dashes and underscores with spaces), and sets that as the alt.

Nice way to cover accessibility and SEO basics without relying on dev time or CMS hacks.

Example:
Code:
<img src="/images/sunset-over-bolton.jpg">

Becomes:
Code:
<img src="/images/sunset-over-bolton.jpg" alt="sunset over bolton">

Nothing groundbreaking, just practical. If you're already using Cloudflare Workers, it’s a quick win.

Heres the Worker Script:
Code:
export default {
  async fetch(request, env, ctx) {
    const response = await fetch(request);

    // Only modify HTML responses
    const contentType = response.headers.get("content-type");
    if (!contentType || !contentType.includes("text/html")) {
      return response;
    }

    const originalHtml = await response.text();

    // Use regex to update image tags
    const modifiedHtml = originalHtml.replace(/<img([^>]*?)>/gi, (match, attributes) => {
      // If the image already has a valid alt, leave it as is
      const hasAlt = /alt\s*=\s*["'][^"']+["']/i.test(attributes);
      if (hasAlt) {
        return `<img${attributes}>`;
      }

      // Get the src value
      const srcMatch = attributes.match(/src\s*=\s*["']([^"']+)["']/i);
      if (!srcMatch) {
        return `<img${attributes}>`; // Skip if no src
      }

      // Extract filename from src
      const src = srcMatch[1];
      const filename = src.split('/').pop().split('?')[0].split('#')[0];
      const altText = filename.replace(/\.[^/.]+$/, '').replace(/[-_]/g, ' '); // remove extension, replace dashes/underscores with spaces

      // Inject the alt attribute
      return `<img${attributes} alt="${altText.trim()}">`;
    });

    return new Response(modifiedHtml, {
      status: response.status,
      statusText: response.statusText,
      headers: {
        'content-type': 'text/html; charset=UTF-8'
      }
    });
  }
};
 
Back
Top