CDN for Media Folder

Hi Everyone,

I’m having some trouble figuring out how to serve images from my media folder via a CDN, particularly thumbs using srcset.

I’m following the Kirby loves CDN cookbook recipe which works okay except that I don’t want the CDN to do the image processing for me, I just want it to serve the file from my media folder.

In the recipe it looks like the file::version component will return a url that processes the options as parameters: /my-file.jpeg?width=320&quality=60&format=webp.

What I’m looking for is just the regular Kirby output: /my-file-320x-q60.webp but with the base changed to include my CDN domain.


Rather than getting too deep into mangling strings, I’m wondering if anyone else has any pointers or good examples of how to achieve something like this?
Is there something simpler? Is there a reason not to do it like this?

Thanks!

Chris

Hey Chris,

by calling

static $original;

$original ??= $kirby->nativeComponent('file::version');

$url = $original($kirby, $file, $options);

in the file::version component, you will get the URL that Kirby would normally build for the thumb. You can then use that as a starting point and replace your domain with the CDN domain for example.

Thanks @bastianallgeier, that helps a lot!

For anyone coming across this in future, the current solution I have is:

'file::version' => function (Kirby $kirby, File $file, array $options = []) {
  static $original;

  $original ??= $kirby->nativeComponent('file::version');
  $use_cdn = ($kirby->option('cdn.active', false) !== false);

  //  If this is an image, use the CDN
  if ($use_cdn && $file->type() === 'image') {
    $original_url = $original($kirby, $file, $options)->url();
    $cdn_url = Str::replace($original_url, $kirby->option('cdn.base'), $kirby->option('cdn.domain'));

    return new FileVersion([
      'modifications' => $options,
      'original' => $file,
      'root' => $file->root(),
      'url' => $cdn_url,
    ]);
  }

  //  Otherwise, return the original
  return $original($kirby, $file, $options);
},
'file::url' => function (Kirby $kirby, File $file): string {
  static $original;

  $original ??= $kirby->nativeComponent('file::url');
  $original_url = $original($kirby, $file);
  $use_cdn = ($kirby->option('cdn.active', false) !== false);

  //  If this is an image, use the CDN
  if ($use_cdn && $file->type() === 'image') {
    $cdn_url = Str::replace($original_url, $kirby->option('cdn.base'), $kirby->option('cdn.domain'));

    return $cdn_url;
  }

  //  Otherwise, return the original
  return $original_url;
}

In my config file, I have:

'cdn' => [
  'active' => true,
  'base' => 'https://my-domain.com',
  'domain' => 'https://cdn.my-domain.com',
],

Thanks for sharing your solution.

1 Like