Utilize Cloudflare Workers To Rewrite Image URLs

With Image Resizing, you can transform images on Cloudflare’s edge platform. You can resize, adjust quality, and convert images to WebP or AVIF format on demand. Cloudflare will automatically cache every derived image at the edge, so you only need to store one original image at your origin.

50,000 monthly resizing requests are included with Business and Pro plans. $9 USD per additional 50,000 resizing requests.

With Cloudflare Workers, you can deploy serverless code instantly across the globe to give it exceptional performance, reliability, and scale.

The first 100,000 Worker requests each day are free and paid plans start at just $5 USD per month for 10-million monthly Worker requests. Offhand, I’m not sure about for the free plan, but it’s $0.50 USD per additional 1-million Worker requests for our paid plan. This makes Workers as much as ten-times less expensive than other serverless platforms.

While we’ve tried WordPress plugins that claim to convert all image URLs within a WordPress installation to make use of Cloudflare’s Image Resizing URL format, we had varying levels of success with them. We’d considered building our own WordPress plugin to do as much, but decided against it.

Instead, we decided to utilize a Cloudflare Worker that would automagically rewrite the image URLs. This was the simplest way for us to implement Image Resizing site-wide, inclusive of both its front-end and back-end (i.e. admin area). It’s not overtly difficult to implement.

Worker

Within your Cloudflare dashboard, navigate to Workers.

  1. Click the Manage Workers button.
  2. Click the Create a Service button.
  3. Change the Service name to whatever you want or leave it as whatever Cloudflare generated. The name won’t affect the functionality of the worker, but can make it easier to identify though.
  4. Under Select a starter, select HTTP handler.
  5. Click the Create service button.
  6. Under the Triggers tab, click for the default route, and select Disable route.
  7. Click the Undeploy button in the popup confirmation.
  8. Under the Resources tab, Click the Quick edit button.
  9. Completely replace the default JavaScript with the following:
async function handleRequest(req) {
    const res = await fetch(req);

    return rewriter.transform(res);
}

class AttributeRewriter {
    constructor(attributeName) {
        this.attributeName = attributeName
    }

    element(element) {
        const attribute = element.getAttribute(this.attributeName);

        if (attribute) {
            element.setAttribute(
                this.attributeName,
                attribute.replace(
                    /https:\/\/yourdomain\.net\//g,
                    'https://yourdomain.net/cdn-cgi/image/format=auto,metadata=keep,onerror=redirect,quality=100/'
                )
            )
        }
    }
}

const rewriter = new HTMLRewriter()
    .on("div", new AttributeRewriter("data-o_data-thumb"))
    .on("div", new AttributeRewriter("data-thumb"))
    .on("img", new AttributeRewriter("data-large_image"))
    .on("img", new AttributeRewriter("data-src"))
    .on("img", new AttributeRewriter("src"))
    .on("img", new AttributeRewriter("srcset"))
    .on("source", new AttributeRewriter("srcset"))
    .on("video", new AttributeRewriter("poster"))

addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
})
  • Replace the 2 instances of yourdomain.net with your actual domain. Be sure that the dot is escaped with a backslash in the first instance.
  • In the example code above, format=auto,metadata=keep,onerror=redirect,quality=100 are the Cloudflare Image Resizing URL format options. These can be modified as needed. Refer to Cloudflare’s documentation for the complete list of available options.
  • In the example code above, lines 28–35 define the HTML elements and their respective attributes where you want the URLs to be rewritten. You can modify this list to suit your needs. However, be certain to specify element attributes known to contain URLs pointing to images only. Otherwise, the URL of a non-image may be rewritten.
  1. Click the Save button.

HTTP Routes

We’ll create six routes. The first will enable the Worker site-wide. The other five will disable it for those routes.

Within your Cloudflare dashboard, navigate to Workers.

  1. Click the Add route button.
  2. In the Add route popup:
    • Route » yourdomain.net/*
    • Service » cloudflare_image-resizing_worker
      • From the drop-down, select the actual name of the Worker that you created above.
    • Environment » production
  3. Click the Save button.
  4. Click the Add route button.
  5. In the Add route popup:
    • Route » yourdomain.net/wp-admin/js/*
    • Service » None
  6. Click the Save button.
  7. Click the Add route button.
  8. In the Add route popup:
    • Route » yourdomain.net/wp-content/*
    • Service » None
  9. Click the Save button.
  10. Click the Add route button.
  11. In the Add route popup:
    • Route » yourdomain.net/wp-includes/js/*
    • Service » None
  12. Click the Save button.
  13. Click the Add route button.
  14. In the Add route popup:
    • Route » yourdomain.net/wp-json/*
    • Service » None
  15. Click the Save button.
  16. Click the Add route button.
  17. In the Add route popup:
    • Route » yourdomain.net/xmlrpc.php*
    • Service » None
  18. Click the Save button.

If your WordPress installation has other API endpoints at different routes, you may want to create additional HTTP routes for your Worker like the second one above, disabling the Worker for those endpoint routes as well.

Assuming that everything has been configured correctly, the image URLs for your Web site should now be automagically rewritten by Cloudflare to make use of their Image Resizing service.

Author

  • I tried to fix the world, but God wouldn't give me his source code.

    Formerly, CEO and lead developer of a technology company, focusing on the merchant services space. Formerly, of WHMCompleteSolution (WHMCS).

    An avid gamer.

Leave a comment

lexical-absolute
lexical-absolute
lexical-absolute
lexical-absolute
%d bloggers like this: