Optimizing transformed image filenames for SEO

When chasing the long tail of SEO, every detail counts.

— Published on March 26, 2021

One of my favourite config settings in Imager X (of which there're sooo many), is filenamePattern. I suspect that I'm somewhat alone in even knowing that it exists, but let me show you how you can utilise it to gain a real-world SEO advantage.

So, what does filenamePattern do? In short, it's a template (or... pattern, duh) that is used to figure out what the filename of a given transform should be. The default value is'{basename}_{transformString|hash}.{extension}', which will result in a transformed image named myfile_5ae402c9837860cd6e4f65e304b3a5fa.jpg, given an asset named myfile.jpg and a transform of { width: 800 }. You could change it to'{basename}_{transformString}.{extension}', and you'd get a transformed image named myfile_W800.jpg. Or, you could change it to 'spacecatninja_{transformString}.{extension}' to get a transformed image named spacecatninja_W800.jpg. You get the idea.

There're four built in template variables which can be used, basename, extension, fullname and transformString, and you can choose to hash them either with |hash or |shorthash. See the documentation for all the details. I addition, you can add whatever static content to the pattern that you want. The question is, why would you want to do that?

Let's say you're building a webshop in a competitive environment where every last bit of SEO advantage counts. The client is lazy/uninformed/stressed (pick one, or refer to one of your clients) and keeps uploading product images named things like DSC_002772.jpg, september001.jpg and jhqwkhhqw.jpg. Not exactly what the Google Images best practices would call "relevant to the subject matter". As long as you've followed all the other best practices, placed the image close to relevant content, added a caption and an alt text, and so on, this wouldn't be a big deal. But as I said, we're in a competitive environment and every... last... drop... of SEO juice counts!

The fix is simple. First, let's recall some Imager 101; almost every single config setting can be overridden when doing a transform, using the fourth parameter of craft.imagerx.transformImage. In our product template, we have the following code that generates the product hero image:

{% set transform = craft.imager.transformImage(
    product.heroImage.one(), 
    [{ width: 800 }, { width: 1600 }], 
    { ratio: 16/9 }, 
    { fillTransforms: true }
) %}

The hero image transforms have names like DSC_002772_5ae402c9837860cd6e4f65e304b3a5fa.jpg. Yuck.

Now, let's assume that you've taken the time to craft a proper slug for you products, pulling in all the important keywords from the product. That string would be a perfect candidate for optimizing the filenames quickly! Let's add in a custom filenamePattern!

{% set transform = craft.imager.transformImage(
    product.heroImage.one(), 
    [{ width: 800 }, { width: 1600 }], 
    { ratio: 16/9 }, 
    { 
        fillTransforms: true, 
        filenamePattern: product.slug ~ '_{transformString|shorthash}.{extension}' 
    }
) %}

That's it, the transforms are now named rayban-rb3447-legend-gold-green_5ae402c9.jpg! Mission accomplished.

One thing that's important to remember when adding custom text to the pattern, is to make sure that the text is valid for filenames. Imager will assume that you know what you're doing, and won't do any additional encoding on it. But, one pretty safe way to achieve this is by combining the ascii and kebab twig filters in your templates.

{% set customName = someText|ascii|kebab %}

{% set transform = craft.imager.transformImage(
    myImage, 
    [{ width: 800 }, { width: 1600 }], 
    { ratio: 16/9 }, 
    { 
        fillTransforms: true, 
        filenamePattern: customName ~ '_{transformString|shorthash}.{extension}' 
    }
) %}

So, that's the hidden gem called filenamePattern. If you're not a fan yet... that's totally ok, and I'm the weirdo (as usual). 🥸