Including Image Name in Cloudflare Images URL

What is the issue or error you’re encountering

I need the image name to be part of the URL for it to work with my image gallery

What steps have you taken to resolve the issue?

I have an image gallery and recently moved the images to Cloudflare Images. However, to integrate properly with my existing code, the image name needs to be part of the image URL.

Currently, the gallery cannot determine which image to display if an identifier like 1-ebd6-414a-88cd-eda3bd0f2700 is used alone. I am using flexible images with parameters, and this works well for generating images with settings like:

https://www.mydomain.com/cdn-cgi/imagedelivery/VxinhlHisdWbCnU_f3zJdA/a5b18f71-ebd6-414a-88cd-eda3bd0f2700/w=1200,sharpen=3

However, I need something like:

https://www.mydomain.com/cdn-cgi/imagedelivery/VxinhlHisdWbCnU_f3zJdA/image-name/w=1200,sharpen=3

to let the system know which image should be displayed by including the image name in the URL.

In other words: Replace the Image ID with the Image Name.
( no need to change the path )

Is there a way to achieve this with Cloudflare Images?

I saw some answers in the forum on this topic, but they were more general and not specific for my case.
( like here: Topic )
If this is possible, could I get more specific help or examples?

Thank you !

I found the solution using

I have an url now like

https://www.mydomain.com/cdn-cgi/imagedelivery/VxinhlHisdWbCnU_f3zJdA/<custom-path>/<image-name>/w=1200,sharpen=3

Chatgpt coded a node.js script for me, that did the trick.

const axios = require('axios');
const fs = require('fs-extra');
const path = require('path');
const FormData = require('form-data');

const API_TOKEN = '<api-token>';
const ACCOUNT_ID = '<account-id>';
const IMAGE_FOLDER_PATH = '<path_to_images>'; 
const BATCH_SIZE = 100; 
const FALLBACK_FOLDER_PATH = '<path>'; 
const MAX_RETRIES = 3; 

fs.ensureDirSync(FALLBACK_FOLDER_PATH);

async function uploadImage(imagePath, retryCount = 0) {
    try {
        const imageName = path.basename(imagePath, path.extname(imagePath)); 
        const customId = `images/${imageName}`; 

        const formData = new FormData();
        formData.append('file', fs.createReadStream(imagePath));
        formData.append('id', customId);

        const response = await axios.post(
            `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/images/v1`,
            formData,
            {
                headers: {
                    'Authorization': `Bearer ${API_TOKEN}`,
                    ...formData.getHeaders()
                },
            }
        );

        console.log(`Upload succesvol: ${path.basename(imagePath)} als ${customId}`);
        return response.data;
    } catch (error) {
        console.error(`Fout bij uploaden van ${path.basename(imagePath)} (poging ${retryCount + 1}/${MAX_RETRIES}):`, error.message);

        if (retryCount < MAX_RETRIES - 1) {
            await new Promise(resolve => setTimeout(resolve, 1000));
            return uploadImage(imagePath, retryCount + 1);
        } else {
           
            const fallbackPath = path.join(FALLBACK_FOLDER_PATH, path.basename(imagePath));
            await fs.copy(imagePath, fallbackPath);
            console.log(`Fallback opgeslagen voor: ${path.basename(imagePath)} naar ${fallbackPath}`);
            return null;
        }
    }
}


async function uploadImagesInBatches() {
    const imageFiles = await fs.readdir(IMAGE_FOLDER_PATH);
    const totalImages = imageFiles.length;

    for (let i = 0; i < totalImages; i += BATCH_SIZE) {
        const batch = imageFiles.slice(i, i + BATCH_SIZE);
        console.log(`Bezig met batch ${i / BATCH_SIZE + 1} van ${Math.ceil(totalImages / BATCH_SIZE)}`);

        const uploadPromises = batch.map((filename) => {
            const imagePath = path.join(IMAGE_FOLDER_PATH, filename);

            if (fs.lstatSync(imagePath).isFile()) {
                return uploadImage(imagePath);
            } else {
                console.warn(`Overgeslagen: ${filename} is een map, geen bestand.`);
                return Promise.resolve(); 
            }
        });

        await Promise.all(uploadPromises);
    }

    console.log('All images uploaded!');
}

uploadImagesInBatches();

Mike is right in that using custom paths is likely to be your best option.

Filename as we use it in Cloudflare Images isn’t unique - you could happily upload two separate files called “cat.jpg” with separate content making it unsuitable for this.

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