Problems with SEO in images urls after migrating to Kirby3

We are having a serious problem with SEO after migrating to Kirby3 due to Kirby3 uses a different path solution to stores the images in a new /media/pages/ path plus a “Hash” code for each image URL.

So, we are getting hundred and hundred of 404 errors and we can’t found a way to redirect them to the new path.

This is the old path:


And this is the new one:


We need help to get any idea of how to handle this error, especially with the “hash” part.

Best Regards,

Is it true that you have a dedicated folder per (original) image?

Because if that’s the case, the root to the new location would be pretty straightforward

    'routes' => [
        'pattern' => 'thumbs/(:all)/(:any)/(:any)',
        'action'  => function ($parent, $original, $filename) {
          if ($page = page($parent)) {
            if ($original = $page->image($original)) {
              go($page->mediaUrl() . '/' . $original->mediaHash() . '/' . $filename);

Hi @texnixe and thanks for your quick reply.

Sorry, I don’t have an image per folder. A folder is a product in our webpage and it could have multiple images: for example:


I was trying a solution like you post here, but the difficult part is to get the image name without the params as sizes and quality (q)

What other solution could I try?

Note: The images in parent could have any name

You could try to get the original image name via some regex voodoo. If you have only used size and quality ideally always the same quality and no other thumb options like blur, b/w, etc., it shouldn’t be tooooooo difficult to get the original filename from the thumb name.

Unfortunately, we need the original to get the hash…

Trying to think about other options…

Another option would be to store the thumbs in a different folder, i.e. a thumbs folder. This can be achieved by creating a fileVersion component in a plugin.

I afraid that!

Do you know what is the pattern/structure like (width x height + quality + bw + etc…) used by Kirby2 for store the thumbnails?

@texnixe we found a solution, it is not perfect but works fine for the most of cases, It reduce a lot the 404 errors. The code is something like this:

 'routes' => [
        'pattern' => 'thumbs/(:all)/(:any).(?:jpg|jpeg|gif|png)',
        'action' => function($parent, $name) {
            $original = null;
            if ($page = page($parent)) {

                // Filter the images whoose name starts with $name
                $possibleImages = $page->images()->filter(function ($image) use ($name) {
                    return Str::startsWith($name, $image->name());

                // Sort by name in order to get the longest name first and
                // get the first coincidence 
                foreach ($possibleImages->sortBy('name', 'desc') as $image) {
                    if (Str::startsWith($name, $image->name())) {
                        $original = $image;

                // The image does not exists
                if (!$original) {

                // Returns a new thumb
                go($original->thumb()->url(), 301);

Thanks for your support.

Great, I’ll leave this open for the moment, maybe someone comes up with a better idea.

Unless you want to create new files in the media folder and thus profit from the new structure, I’d pursue the alternative solution with storing the files in a thumbs folder as suggested above.