How to preserve image filenames in Sanity CDN URLs for SEO?

6 repliesLast updated: Nov 29, 2025

Hey everyone 👋 long-time lurker, first-time poster. I’ve been building sites and templates with Gatsby/Sanity together for a while now and along the way a fair few clients have asked me how to preserve image filenames in generated CDN URLs for SEO visibility. I’ve got as far as manipulating the
originalFilename
, but I can’t find anything on how Sanity manages filename generation when exporting imagery out to and hosting on the CDN. If anyone has any experience in this realm your help or advice would be much appreciated
AI Update

Great question! You're on the right track with originalFilename – this is exactly what you need for creating SEO-friendly image URLs.

Sanity supports what they call "vanity filenames" which lets you append a human-readable filename to the end of the hashed image URL. This gives you the SEO benefits you're looking for without changing how the CDN fundamentally works.

How Vanity Filenames Work

The CDN URL format is:

https://cdn.sanity.io/images/<projectId>/<dataset>/<hashedFileName>/<vanityFilename>?<params>

So instead of:

https://cdn.sanity.io/images/1234567/production/754c8d64997b668642bd2500f833722c6293cf8b-1766x1065.png?q=75&fit=clip&auto=format

You can have:

https://cdn.sanity.io/images/1234567/production/754c8d64997b668642bd2500f833722c6293cf8b-1766x1065.png/my-product-image.png?q=75&fit=clip&auto=format

The hash stays in the URL (it's required for the CDN's content-addressable architecture), but you get the human-readable filename at the end, which is what search engines care about.

Implementation with Gatsby

For Gatsby specifically, you'll need to:

query {
  allSanityYourType {
    nodes {
      image {
        asset {
          url
          originalFilename
          # other fields you need
        }
      }
    }
  }
}

Here's a practical example:

import imageUrlBuilder from '@sanity/image-url'

const builder = imageUrlBuilder(sanityConfig)

function urlFor(source, originalFilename) {
  const baseUrl = builder.image(source).url()
  return originalFilename ? `${baseUrl}/${originalFilename}` : baseUrl
}

// Usage:
const imageUrl = urlFor(image.asset, image.asset.originalFilename)

Important Notes

The hash-based filename is actually a feature, not a bug – it enables Sanity's content-addressable storage system where the URL itself is derived from the content, making cache invalidation automatic and bulletproof. The vanity filename gives you the best of both worlds: reliable caching and SEO-friendly URLs.

Show original thread
6 replies

Was this answer helpful?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Related contributions