How To

Cloudflare image optimisation for Webflow: our Image Resizer Worker script explained

Preferred source on google logo
Cloudflare image optimisation for Webflow: our Image Resizer Worker script explained
July 21, 2023

  · 12 min

The Cloudflare Worker script we used in 2023 to optimise and cache Webflow images with Cloudflare Image Resizer, plus the DNS and Worker setup steps and a short FAQ.

Update, October 2026: Things have moved on since I wrote this. The newer approach is in Free Webflow image optimisation with Cloudflare (2026): our open-source O2O Worker. The rest of this post still stands as a record of how we did it at the time.

Original post

Today, we're going to take a magical journey into the heart of a Cloudflare worker script we've been using to optimise images on our Webflow project. It's a bit like taking a peek under the hood of a sports car, except instead of oil and pistons, we're dealing with JavaScript and regular expressions. 

We’ve already done an in-depth post on setting up Cloudflare, but here we’ll take a different approach. For the original post on getting Webflow cached on Cloudflare and using the Cassette App in Cloudflare to cache your assets that live on the Webflow CDN in Cloudflare, head to this post: Using Webflow with Cloudflare to cache and speed up your Webflow project 

The method used in the previous post relied on using Cassette to cache all Webflow assets on a subdomain of your choosing. It could become a bit complicated for small Webflow agencies or freelancers who don’t have much experience with this kind of thing, and while the below isn’t as complicated, it still involves editing our code to make it work for you. With the method below we’ll be using a different approach. 

The initial DNS setup process remains the same, and we’ll give a brief rundown at the end of this post, but the rest of the setup process branches off there. Instead of relying on Cloudflare’s Cassette App to cache your assets and then replace the links in your code, we only focus on images with this new approach and we won’t be caching and replacing CSS file links, JavaScript files or fonts. Some folks experienced issues where Cloudflare’s Rocket Loader would load their code later on, messing with interactions etc., so if you found it hard to exclude the relevant JS and CSS files, this method might work better for you.

Here, we use a Cloudflare worker to find all links to images that aren’t SVGs (and therefore already optimised, we do still cache the SVGs). It then optimises them using the Cloudflare Image Resizer by replacing all image links in your Webflow project with Cloudflare Image Resizer links. This allows Cloudflare to not only optimise images that aren’t on your domain name (the Webflow CDN domain), but also to cache them for future use.

Sounds fun, right? Just a reminder: just like our other post, this is advanced, so please read carefully. Let's get into it!

Our Webflow Cloudflare Image Resizer Worker script

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Worker Script" src="https://codepen.io/milkmoonstudio/embed/LYXrvaW?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/LYXrvaW">
Cloudflare Image Resizer - Worker Script</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

The above script is what is running on Milk Moon Studio right now, therefore it’s set up for us. You would have to replace our domain, milkmoonstudio.com, in two places in this script, and potentially update both regular expressions in the script if your images are not stored on https://assets.website-files.com or their prod domains like our assets are. More on that later.

Let’s see what the Cloudflare Worker’s doing

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Fetch Events" src="https://codepen.io/milkmoonstudio/embed/ZEmRNLW?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/ZEmRNLW">
Cloudflare Image Resizer - Fetch Events</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Our script is always on the lookout for fetch events. When one comes in, it springs into action and calls our ‘handleRequest’ function.

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - HandleRequest" src="https://codepen.io/milkmoonstudio/embed/bGQKygy?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/bGQKygy">
Cloudflare Image Resizer - HandleRequest</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Our handleRequest function is like a personal assistant, fetching the request and checking its 'Content-Type'. If it can't find a 'Content-Type', it just assumes it's an empty string.

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Content Type" src="https://codepen.io/milkmoonstudio/embed/QWJxRvL?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/QWJxRvL">
Cloudflare Image Resizer - Content Type</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

If the 'Content-Type' tells us it's an HTML document, we get the text of the response. This is like opening up the package and checking out what's inside.

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image resizer - Find Images" src="https://codepen.io/milkmoonstudio/embed/YzRjKPY?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/YzRjKPY">
Cloudflare Image resizer - Find Images</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Here's where we start optimising. We find any image URLs that point to the Webflow CDN and replace them with URLs that point to our Cloudflare worker. This is like redirecting the mail to a more efficient post office.

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - SRC Sets" src="https://codepen.io/milkmoonstudio/embed/ZEmjzQb?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/ZEmjzQb">
Cloudflare Image Resizer - SRC Sets</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Next, we tackle the srcset attributes. These can contain multiple URLs, so we use a function to replace each one. It's like having a list of addresses and updating each one to a new location. This caused some issues in the previous Cloudflare implementation with Cassette. Webflow generates SRC Sets. Essentially, a list of different sizes of each image in the project resized for various screen widths. This optimisation on the Webflow side did, however, mean that Cassette only replaced one or two image links in an SRC Set, and then missed others. We tried for broad matches here and experimented a lot to try and catch the full set with this bit, while the code block above looked for images that don’t have SRC Sets, so covering our bases on all ends.

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Re-package" src="https://codepen.io/milkmoonstudio/embed/wvQxwWN?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/wvQxwWN">
Cloudflare Image Resizer - Re-package</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Once we've done all our replacements, we pack everything back up into a new response and send it on its way. It's like repackaging our opened box and sending it off to its final destination.

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Error check and response" src="https://codepen.io/milkmoonstudio/embed/poQZzNv?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/poQZzNv">
Cloudflare Image Resizer - Error check and response</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

If our package isn't an HTML document, we just send it on its way without opening it. If something goes wrong, we log the error and return a 500 response. It's like saying, "Oops, something went wrong. We'll try again later."

And that's it! That's how our Cloudflare worker script optimises images on our Webflow projects. It's a bit like a super-efficient post office, redirecting mail and making sure everything gets to where it needs to go as quickly and efficiently as possible.

Update: assets.website-files.com, assets-global.website-files.com and cdn.prod.website-files.com

We were actually recently randomly switched from assets to assets-global, so I’ve got an updated Worker script below and we’ve also added the new https://cdn.prod.website-files.com. Just adapt with your custom domain:

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer Worker Script - For assets.website-files.com and assets-global.website-files.com" src="https://codepen.io/milkmoonstudio/embed/qBLGwjp?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/qBLGwjp">
Cloudflare Image Resizer Worker Script - For assets.website-files.com and assets-global.website-files.com</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Steps to implement

So, aside from that, what do you need to do?

  1. Set up the required DNS settings in Cloudflare to allow caching.
  2. Update the code with your own domain instead of milkmoonstudio.com.
  3. If your assets are not stored on assets.website-files.com like ours were, update both sets of regular expressions that look for the Webflow CDN URLs. We’ve tried to add as many of the CDNs as we can, but we might have missed some.
  4. Add the Cloudflare Worker! Paid Worker, remember that.
  5. Turn on Image Resizer / Image Transformations, it’s paid for.

1. Webflow DNS settings in Cloudflare

Alright, folks, it's time to get our hands dirty with some DNS settings. Now, you might be thinking, "Wait a minute, didn't we cover this in a previous post?" And you'd be right! But we're going to shake things up and add it again for those who don’t have the time to read our original Webflow and Cloudflare caching post as well.

Now, Webflow is going to give you a couple of instructions here. They'll tell you to add two A records and a CNAME record when you enable SSL in your Webflow Hosting tab (and these days, they'll also give you a TXT record). They'll also tell you to turn off proxying on Cloudflare (that's the orange cloud icon). But we're going to go rogue and ignore all that.

When you enable SSL, you'll see instructions that look something like this:

Webflow DNS settings

Webflow DNS settings

But we're going to say "Thanks, but no thanks!" to these instructions. Here's what you should do instead:

  • First off, turn off SSL at the bottom of the hosting tab and hit Save.
Disable SSL

Disable SSL

  • Next, copy the new A record addresses and the CNAME settings:
Save the non-ssl Webflow DNS settings

Save the non-SSL Webflow DNS settings

  • Now, turn the SSL tick box back on and save. You'll see the settings revert to the initial SSL settings, but just ignore those.
  • Head over to Cloudflare and add the non-SSL DNS settings. It should look something like this:
Add Webflow DNS settings to Cloudflare

Add Webflow DNS settings to Cloudflare

  • You can add the correct TXT record like Webflow asked: proxy-ssl.webflow.com.
  • Make sure the entries have Proxied turned on, even though Webflow's Cloudflare instructions tell you otherwise.
  • Go to the SSL/TLS settings tab in Cloudflare and turn on Full:
Set SSL to Full in Cloudflare

Set SSL to Full in Cloudflare

  • Head back to Webflow's Hosting tab.
  • Yikes, that's a lot of issues! But don't worry, just ignore them and publish the site.
Ignore the Webflow DNS erros

Ignore the Webflow DNS errors

And that's it! You've successfully navigated the wild world of Cloudflare DNS settings for Webflow. Give yourself a pat on the back, you’re now caching on Cloudflare, well, apart from the assets.

2. Update the Cloudflare Worker script with your own domain

All you need to do here is find the milkmoonstudio.com bit, there’s two, and change it to the domain name you have in Cloudflare. It’s right in the middle where the worker will look for the image URLs and replace them. Here it is below:

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Replace your personal domain" src="https://codepen.io/milkmoonstudio/embed/gOQjYeq?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/gOQjYeq">
Cloudflare Image Resizer - Replace your personal domain</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

3. Update both sets of regular expressions

So this is very very important. In our case the Webflow CDN stored all assets for the project on https://assets.website-files.com, but this is not always the case and varies from project to project. So just like in our other Cloudflare post, you’ll have to change this based on the domain your images are stored on. You can inspect the code, or open an image in a new tab to check. Popular Webflow CDN domains are:

  • https://assets.website-files.com
  • https://website-files.com
  • https://uploads-ssl.webflow.com 
  • https://global-uploads.webflow.com
  • https://cdn.prod.website-files.com

We have no idea how many there are or how they’re chosen, but these are a few we’ve seen.

If you’re lucky, you know something about regular expressions and it’ll be easy to update. If not, look at some of the examples we’ve put together below, you should be able to figure it out. You’ll have to update both and this is basically what the Cloudflare Worker will be looking for:

Regular expressions for https://assets.website-files.com

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Regex Example 1" src="https://codepen.io/milkmoonstudio/embed/zYMLOMd?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/zYMLOMd">
Cloudflare Image Resizer - Regex Example 1</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Regular expressions for https://assets.website-files.com

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Regex Example 2" src="https://codepen.io/milkmoonstudio/embed/jOQpNdq?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/jOQpNdq">
Cloudflare Image Resizer - Regex Example 2</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Regular expressions for https://global-uploads.webflow.com

<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Regex Example 3" src="https://codepen.io/milkmoonstudio/embed/mdQjbvo?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/mdQjbvo">
Cloudflare Image Resizer - Regex Example 3</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

Depending on your CDN asset domain you might have to mess around a bit, and yeah, we also suck at this, I mean \/[^\s"']+\ 🤮

4. Adding the Cloudflare Worker and Worker route

So, you’ve made the DNS changes, you’ve updated the script, and you should have something like this:
<iframe height="300" style="width: 100%;" scrolling="no" title="Cloudflare Image Resizer - Worker Script" src="https://codepen.io/milkmoonstudio/embed/LYXrvaW?default-tab=js" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/milkmoonstudio/pen/LYXrvaW">
Cloudflare Image Resizer - Worker Script</a> by Jakes van Eeden (<a href="https://codepen.io/milkmoonstudio">@milkmoonstudio</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>

What now? You’ll have to do 4 things: add a Cloudflare Worker plan, enable Image Resizing, create the Worker and add the Worker route.

Head to Workers & Pages, click Plans and add a Plan. There is a free tier. No idea if this’ll work, we have a plan, so you can try the free tier and let us know.

Cloudflare Worker Plan Selection

Cloudflare Worker Plan Selection

Next, open your domain settings, go to Speed, Optimization and then Image Optimization, and enable Image Resizing:

Enable Image Resizing

Enable Image Resizing

The next step is creating the Worker and adding the script. Go back to the main menu, and then Workers & Pages. Click Create Application, then click Create Worker.

Create a Worker Application

Create a Worker Application

Create a Cloudflare Worker

Create a Cloudflare Worker

Give it a name and Deploy.

Name the Cloudflare Worker

Name the Cloudflare Worker

Edit the code and remove what was in there and paste in your script, and then hit Save and Deploy.

Add the script to the Worker

Add the script to the Worker

Finally, go back to your website settings page, select the Workers Routes tab and add a route. Select the worker and give it the route. I want it running everywhere, so it’s got wildcards: *.milkmoonstudio.com/*

Add the Worker route

Add the Worker route

Now you’re done and can test the site to see if it’s working.

Change the Image Resizer settings (optional) 

If you look at the actual Image Resizer URL in the worker script we’re using to replace the Webflow image in the page code, we’re using fairly basic settings:

https://milkmoonstudio.com/cdn-cgi/image/f=auto,quality=90/

F is for format and we have Auto, so it’ll check the browser, device, connection etc. and decide on a format. AVIF is done on a best effort basis, otherwise WebP etc. if there’s support. There are also restrictions on image size and dimension when it comes to conversion for AVIF etc. You’ll also see we made the images lossy at 80% quality. There are many many more options that you can find in Cloudflare’s URL format docs and add. Just remember, when looking at the option you want to implement, to follow the URL format, as you’re placing the given option in a URL.

You can now use Page Rules to cache everything (these days that’s done with Cache Rules, as Page Rules are being phased out). More on that in our original Cloudflare caching post, so check it out if you need help.

Feel free to drop a comment below and check out our other Cloudflare-related posts:

Free Webflow image optimisation with Cloudflare (2026): our open-source O2O Worker

Using Webflow with Cloudflare to cache and speed up your Webflow project

Boost Page Speed: Cloudflare Zaraz & Google Analytics

We’re planning on doing a video how-to so stay tuned.

The easiest way to test your setup is using the DrFlare Extension. Launch DrFlare from Dev Tools and refresh the page. You’ll see detailed stats and can hover over images etc. for on-site analysis.

Frequently asked questions

How do I optimise Webflow images with Cloudflare?

You put a Cloudflare Worker in front of your site that rewrites every Webflow CDN image link to a Cloudflare Image Resizer link, so Cloudflare converts, compresses and caches the images for you. That's what the script above does. If you're starting fresh today, use the 2026 Cloudflare asset proxy and optimisation guide instead.

What is cdn.prod.website-files.com?

It's one of the Webflow CDN domains your uploaded images, files and fonts are served from. Which domain a project uses varies, which is why the regular expressions in step 3 have to match yours.

Do I need a paid Cloudflare plan for this?

Not necessarily. According to Cloudflare's pricing, the Workers free plan covers 100,000 requests a day and Image Transformations includes 5,000 unique transformations a month, so a small site can try it for free. We run a paid Workers plan, and busier sites will need one.

Does this Webflow and Cloudflare image setup still work?

It did when we wrote it, and the approach is still how we optimise images, but the details have changed. Cloudflare Image Resizer is now Image Transformations, Page Rules are being replaced by Cache Rules, and our current Worker signs its image URLs and runs on Webflow's Orange-to-Orange setup. The 2026 guide covers all of that.

For more on the wider speed picture, have a look at our post on how page speed drives business success, and on flushing your DNS cache after a Webflow publish. If you'd like us to set this up for you, get in touch.

Preferred source on google logo

Share

All Posts

Gradient Background