Worker to draw overlay images

I am trying to overlay watermark on the images via cloudflare workers
I tried the sample code from the documentation, but it returns the original image only.

addEventListener("fetch", event => {

* Fetch and log a request
* @param {Request} request
async function handleRequest(request) {
// Parse request URL to get access to query string
let url = new URL(request.url)

// Cloudflare-specific options are in the cf object.
let options = { cf: { image: {} } }

// Copy parameters from query string to request options.
// You can implement various different parameters here.
if (url.searchParams.has("fit")) = url.searchParams.get("fit")
if (url.searchParams.has("width")) = url.searchParams.get("width")
if (url.searchParams.has("height")) = url.searchParams.get("height")
if (url.searchParams.has("quality")) = url.searchParams.get("quality")
if (url.searchParams.has("rotate")) = url.searchParams.get("rotate")

// Your Worker is responsible for automatic format negotiation. Check the Accept header.
const accept = request.headers.get("Accept");
if (/image\/avif/.test(accept)) { = 'avif';
} else if (/image\/webp/.test(accept)) { = 'webp';

// Get URL of the original (full size) image to resize.
// You could adjust the URL here, e.g., prefix it with a fixed address of your server,
// so that user-visible URLs are shorter and cleaner.
const imageURL = url.searchParams.get("image")
if (!imageURL) return new Response('Missing "image" value', { status: 400 })

try {
// TODO: Customize validation logic
const { hostname, pathname } = new URL(imageURL)

// Optionally, only allow URLs with JPEG, PNG, GIF, or WebP file extensions
// @see
if (!/\.(jpe?g|png|gif|webp)$/i.test(pathname)) {
return new Response('Disallowed file extension', { status: 400 })

// Demo: Only accept "" images
// if (hostname !== '') {
// return new Response('Must use "" source images', { status: 403 })
// }
} catch (err) {
return new Response('Invalid "image" value', { status: 400 })

// Build a request that passes through request headers
const imageRequest = new Request(imageURL, {
headers: request.headers

// Returning fetch() with resizing options will pass through response with the resized image.
return fetch(imageRequest, options)

I even tried a simple code where I used hardcoded image in the worker and just applied rotation, it still returns the original image

return fetch("", {cf: {image: {rotate: 90}}})

Hi there,

thank you for contacting Cloudflare.

Blake with the Support team here, I will be assisting you today on this community post.

Is there a specific document you are referencing? Ex: Draw overlays and watermarks · Cloudflare Image Optimization docs

We have some documentation if using Image Resizing, are you using a resized image for this, or are you wanting to use any images?

We cannot debug code, but we would be happy to point you in the right direction here.

1 Like

Is this on Have you enabled image resizing?


Thank you Blake,
Yes I am using the same doc Draw overlays and watermarks · Cloudflare Image Optimization docs
I want to use any image and apply watermark to it.

Yes I have enabled image resizing
this is the preview url
this is an example

this image should get rotated but its not in original form

I am not sure Image Resizing works on the domain. Please try deploying the Worker on the same zone that you enabled Image Resizing.

Thats right, It is now working when I deploy it on my zone.
Thank you for the help :smile:


This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.