Help implement CDN

Hi,

I recently started a new blog using Kirby. You can look at it at https://emanuelpina.pt

Today, I’m asking for help to implement a CDN solution for my use case.

And what’s my use case?

I use Bunny as CDN. I don’t want to use their image optimization service. So all I want is that my assets and media files are served by the CDN.

So, instead of emanuelpina.pt/assets/my-asset.css I want Kirby to look for cdn.emanuelpina.pt/assets/my-asset.css

Instead of emanuelpina.pt/media/my-image.jpg I want Kirby to look for cdn.emanuelpina.pt/media/my-image.jpg

And instead of emanuelpina.pt/media/my-image-100x100-crop-right-q90.jpg I want Kirby to look for cdn.emanuelpina.pt/assets/my-100x100-crop-right-q90.jpg

Following the Kirby loves CDN recipe I was able to achieve what I wanted for css and svg files on assets folder, but not for images or other files.

The above recipe was made to be used with KeyCDN image process service and as I understand I need to implement the file::version and file::url differently of what’s in the recipe. The problem is that I can’t figure how. Can someone help me finding the solution to my use case?

My current plugins\cdn\index.php:

<?php

load([
	'kirby\\cdn\\cachebuster' => __DIR__ . '/src/Cachebuster.php'
]);

use Kirby\Cdn\Cachebuster;

Kirby::plugin('emanuelpina/cdn', [
    'components' => [
        'url' => function ($kirby, $path, $options) {
            if (Str::startsWith($path, 'assets')) {
                $path = Cachebuster::path($path);

                if (option('cdn', false) !== false) {
                    return option('cdn.domain') . '/' . $path;
                }
            }

            $original = $kirby->nativeComponent('url');
            return $original($kirby, $path, $options);
        }
    ]
]);

Thanks

1 Like

I found a solution for my use case. So, let me share it in case someone is looking for something similar and so a more experience user can review if my solution is any good or if there’s a simple/best way to achieve the same.

I found that I could define a custom url for media in index.php:

<?php

include __DIR__ . '/kirby/bootstrap.php';

// if cdn enabled define custom media url
if (option('cdn', false) !== false) {
    $kirby = new Kirby([
        'urls' => [
            'media'  => option('cdn.domain') . '/media',
        ]
    ]);
} else {
    $kirby = new Kirby;
}

echo $kirby->render();

Why not do the same for assets? Because I found that doing that would break the cache busting. I tried several methods/plugins without success.

So, for asset files, I kept the cdn plugin built with the help of Kirby loves CDN recipe. Excluding the Serving files and Image processing parts, of course. So, my plugins\cdn\index.php only has the url component as shown in my first post.

Hope this can help someone’s looking to implement a similar solution. Please, if you have something to add do not hesitate.

Keep in mind that CDNs aren’t always a good solution. For my case I ended up disabling it as perfomance was even worse. The explanation is simple. As my blog has little traffic and I’m still doing changes everyday, the CDN often didn’t have the files cached and had to fetch them from the source, increasing the response time.

1 Like

Wow, this is great!

I would like to thank you for writing up your solution despite no-one answering your initial question!

I had this exact same with and issue with Bunny CDN, and this completely solved it. :pray:

I’m glad it was useful to you. I need to revisit this. For sure, there has to be a more simple and elegant solution to handle assets and cachebusting.