Count images in array of content blocks with GROQ

2 replies
Last updated: Sep 7, 2023
Is there a quick and easy way to count all images in an array of content blocks in GROQ? I’m adding a small text summary like
12 minute read and 43 images
to article teasers. Managed to handle word count no problem, just thinking about a query for counting images. I have a few different content blocks with images, so I assume the query might be complex
AI Update

Yes! There's actually a pretty straightforward way to count images across different content blocks using count() and math::sum() in GROQ.

Here's the basic approach:

*[_type == "article"] {
  title,
  "imageCount": count(content[_type == "image"]) 
    + coalesce(math::sum(content[_type == "gallery"].images[].count(*)), 0)
    + coalesce(math::sum(content[]{count(images)}), 0)
}

But the exact query depends on your schema. Here's a more flexible pattern that handles multiple block types with images:

*[_type == "article"] {
  title,
  "imageCount": 
    // Count standalone image blocks
    count(content[_type == "imageBlock"])
    // Add images from gallery blocks
    + math::sum(
        content[_type in ["imageGalleryBlock", "inlineImagesBlock"]] {
          "count": count(images)
        }.count
      )
}

The key is:

  1. Use count() for simple arrays of image blocks
  2. Use math::sum() combined with count() when you have nested arrays (like galleries)
  3. Filter by _type to target specific block types

If you want to get fancy and combine it with your word count for the teaser:

*[_type == "article"] {
  title,
  "readTime": round(length(pt::text(content)) / 200),
  "imageCount": count(content[_type == "imageBlock"]) 
    + math::sum(content[_type == "gallery"]{count(images)}.count)
}

Then in your frontend you can format it as "12 minute read and 43 images".

The GROQ count() function documentation has more details, and there's a helpful community answer that covers this exact use case with portable text content!

Show original thread
2 replies
I’ve written this query, which works, but seems like it might be over complicated:

"imageCount": math::sum(
  content[] {
    "count": 0,
    _type == "imageBlock" => {
      "count": 1, 
    },
    _type in ["imageGalleryBlock", "inlineImagesBlock"] => {
      "count": length(images[]),
    },
  }.count
),
I’ll stick with this for now, but could there be any more elegant implementations?
Not sure if more elegant, but:
count(content[_type == "imageBlock"])
+ math::sum(
    content[_type in "imageGalleryBlock", "inlineImagesBlock"] {
      "count": count(images)
    }.count
  )
Would be simpler if we had a flatten function, but we don't yet.

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?