Get unique subcategory paths for author's articles in Sanity GROQ

5 replies
Last updated: Nov 29, 2025
Is there a nice way to get the subcategory of all the articles a particular author has written? I did something like
export const conferencesAuthorHasWrittenFor = groq`
  *[_type == 'author' && slug.current == $slug && archived == false][0]{
    "conferencesWrittenFor": *[_type == 'post' && references(^._id)] | order(publishedAt desc, _updatedAt desc){
      "subcategory": subcategory->{title, 'slug': slug.current, "parentSlug": parent->slug.current, "parentTitle": parent->title}
    },
  }
`
but that gives me an array of objects that have
subcategory: [Object]
or
subcategory: null
in them. Ideally I would like to have it return an array of strings like
/news/${parentCategory}/${subCategory}
oh and I want to make them unique
AI Update

Looking at your GROQ query, you're on the right track! To get unique subcategory paths as strings, you'll need to use array manipulation and the array::unique() function. Here's how to refactor your query:

export const conferencesAuthorHasWrittenFor = groq`
  *[_type == 'author' && slug.current == $slug && archived == false][0]{
    "conferencesWrittenFor": array::unique(
      *[_type == 'post' && references(^._id)] {
        "subcategory": subcategory->{title, 'slug': slug.current, "parentSlug": parent->slug.current, "parentTitle": parent->title}
      }.subcategory[defined(@)]
      | order(parentSlug, slug)
      {"path": "/news/" + parentSlug + "/" + slug}
      .path
    )
  }
`

Here's what's happening:

  1. .subcategory[defined(@)] - After projecting the subcategory objects, we access the subcategory field and filter out any null values using [defined(@)]

  2. String concatenation - In the next projection, we build your desired path format: "/news/" + parentSlug + "/" + slug

  3. .path - This extracts just the path string from each object, giving you an array of strings instead of objects

  4. array::unique() - This wraps the entire expression to remove duplicates

The result will be a flat array of unique strings like:

["/news/tech/ai", "/news/design/ux", "/news/tech/web"]

The GROQ Functions Reference documents array::unique() along with other useful array functions. You can also check out the Query Cheat Sheet for more examples of array manipulation patterns.

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