Change Image URL to a CDN

Since the major adoption of Responsive Images and the addition of new srcset attribute to the <img> element. WordPress has to evolve too. WordPress 4.4 added the responsive images feature.

If you inspect the src attribute it might point to the CDN, however, you still need to consider the srcset attribute which might still be using the local version of the images.

First, we need to provide the algorithm for changing the local URL to the CDN version. The algorithm I use adheres your test case above; i.e. https://test.com/ to https://cdn.test.com/

Add these to functions.php

// Add .cdn after http:// or https://
function to_cdn($src) {
    $dslash_pos = strpos($src, '//') + 2;

    $src_pre  = substr($src, 0, $dslash_pos); // http:// or https://
    $src_post = substr($src, $dslash_pos); // The rest after http:// or https://

    return $src_pre . 'cdn.' . $src_post;
}

Then we need to change the src attribute of the image using the wp_get_attachment_image_src filter.

function test_get_attachment_image_src($image, $attachment_id, $size, $icon) {
    if(!is_admin()) {
        if(!image) {
            return false;
        }

        if(is_array($image)) {
            $src = to_cdn($image[0]); // To CDN
            $width = $image[1];
            $height = $image[2];

            return [$src, $width, $height, true];

        } else {
            return false;
        }
    }

  return $image;

}
add_filter('wp_get_attachment_image_src', 'test_get_attachment_image_src', 10, 4);

Next is for the srcset attribute this time using wp_calculate_image_srcset filter.

function test_calculate_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id) {
    if(!is_admin()) {
        $images = [];

        foreach($sources as $source) {
            $src = to_cdn($source['url']); // To CDN
            $images[] = [
                'url' => $src,
                'descriptor' => $source['descriptor'],
                'value' => $source['value']
            ];
        }

        return $images;
    }

  return $sources;
}
add_filter('wp_calculate_image_srcset', 'test_calculate_image_srcset', 10, 5);

Leave a Comment