Sanity image-url shortcode error: "Cannot read property 'replace' of null

8 replies
Last updated: Jan 28, 2026
I’m trying to update the sanity 11ty blog starter to display the images. I’m using @sanity/image-url to get the url and have generated a couple of shortcodes as shown in the sanity docs but I keep getting the following error:
Template render error: (/web/_includes/postslist.njk)
sanity-eleventy-blog-web:   TypeError: Cannot read property 'replace' of null
the error message goes away when I remove the shortcode from the nunjucks template, e.g.

<img src="{% croppedUrlFor currentPost.mainImage, 600, 600 %}" alt="{{ currentPost.mainImage.alt }}">
anyone know what might be causing this?
AI Update

The error "Cannot read property 'replace' of null" suggests that @sanity/image-url is receiving a null value where it expects a valid image reference. This typically happens when the mainImage field is either missing, null, or doesn't have the expected structure.

Here are the most common causes and solutions:

1. Check if the image exists before rendering

The most likely issue is that some posts don't have a mainImage set. Wrap your shortcode in a conditional check:

{% if currentPost.mainImage %}
  <img src="{% croppedUrlFor currentPost.mainImage, 600, 600 %}" alt="{{ currentPost.mainImage.alt }}">
{% endif %}

2. Verify your GROQ query includes image metadata

Make sure your query that fetches posts includes the complete image object structure. Your query should look something like:

*[_type == "post"] {
  _id,
  title,
  mainImage {
    asset->{
      _id,
      url
    },
    crop,
    hotspot,
    alt
  }
}

Without the asset-> expansion, you'll only get a reference, not the actual image data that @sanity/image-url needs.

3. Check your shortcode implementation

Your Eleventy shortcode should handle null values gracefully. Your shortcode might look like:

const imageUrlBuilder = require('@sanity/image-url')
const client = require('./client') // your sanity client

const builder = imageUrlBuilder(client)

eleventyConfig.addShortcode("croppedUrlFor", function(source, width, height) {
  if (!source || !source.asset) {
    return ''; // or return a placeholder image URL
  }
  return builder.image(source).width(width).height(height).url()
});

4. Add null safety to your template

Even with the conditional check, add a fallback for the alt text:

{% if currentPost.mainImage %}
  <img src="{% croppedUrlFor currentPost.mainImage, 600, 600 %}" 
       alt="{{ currentPost.mainImage.alt or 'Blog post image' }}">
{% endif %}

The replace error specifically comes from the URL builder trying to process the asset ID string internally, so ensuring you're passing a complete image object with an asset reference (and handling cases where it's null) should resolve the issue.

Show original thread
8 replies

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.

Was this answer helpful?