How to query span text within block types using GROQ?

24 replies
Last updated: Jan 28, 2026
Hi here, I would like to know how can I get the text of each span within block types using GROQ?
Example:


{
  // ...
  "description": [
    {
      "_key": "1c68d5f6b2a3",
      "_type": "block",
      "children": [
        {
          "_key": "c33a78ff1695",
          "_type": "span",
          "marks": [],
          "text": "A synergistic blend of bioavailable vitamins C & D, herbs, NAC and zinc designed to help improve your long-term immune response."
        }
      ],
      "markDefs": [],
      "style": "normal"
    },
    // ...
  ],
  // ...
}

AI Update

To extract the text from each span within block types using GROQ, you can use array traversal and projection. Here's how:

Basic Text Extraction

To get all the text from spans in a single block content field:

*[_type == "yourDocumentType"] {
  "plainText": description[].children[].text
}

This flattens all the text values from all spans across all blocks into a single array.

Joining Text into a String

If you want to join the text together (similar to the example in the Presenting Portable Text guide):

*[_type == "yourDocumentType"] {
  "plainText": array::join(description[].children[].text, " ")
}

This uses the array::join() function to concatenate all text with spaces between them.

Preserving Block Structure

To maintain the block structure while extracting text from each block separately:

*[_type == "yourDocumentType"] {
  description[] {
    _key,
    _type,
    "text": array::join(children[].text, "")
  }
}

This gives you an array where each block has its combined text.

Filtering by Block Type

To only get text from specific block types (like paragraphs):

*[_type == "yourDocumentType"] {
  "paragraphText": description[_type == "block"].children[].text
}

Complete Example

Based on your example structure, here's a complete query:

*[_type == "product"] {
  _id,
  "descriptionText": array::join(description[].children[].text, " "),
  "descriptionBlocks": description[] {
    _key,
    style,
    "blockText": array::join(children[].text, "")
  }
}

This gives you both a flattened version of all text and a structured version with text per block.

The key pattern is using description[].children[].text to traverse from the block array → into each block's children array → and extract each span's text property. You can then use array::join() to concatenate the strings as needed.

Show original thread
24 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?