How to filter articles by category slug when categories is an array of references?

7 replies
Last updated: Jul 31, 2023
Hello everyone, I have a problem with croq query
  const query = groq`*[_type == "article" && references("category", "categories[]->slug", "${slug}")] {
    ...,
    categories[]-> {
      title,
      slug
    }  
  }
I am on the category page and I try to get all the articles that contain my category slug "${slug}" in the ctegories list. The thing is that the category list "array" is a list of references from Category. Now my query brings nothing. Did you already face it ?
AI Update

I can help you fix this GROQ query issue! The problem is with how you're trying to use the references() function. The syntax you have isn't valid GROQ.

The references() function is actually much simpler than what you're attempting. It takes a document ID and checks if any reference field in the document points to it. You don't specify field paths or slugs - it just checks all reference fields automatically.

Here's the corrected query:

const query = groq`*[_type == "article" && references($categoryId)] {
    ...,
    categories[]-> {
      title,
      slug
    }  
}`

The key changes:

  1. Pass the category document ID, not the slug. The references() function checks against _id values, not slug fields.
  2. Use a parameter ($categoryId) instead of string interpolation for safety and proper typing.

In your code, you'll need to:

  1. First fetch the category document to get its _id:
const categoryDoc = await client.fetch(
  `*[_type == "category" && slug.current == $slug][0]`,
  { slug }
)
  1. Then use that ID in your articles query:
const articles = await client.fetch(query, { categoryId: categoryDoc._id })

Alternative: If you must filter by slug directly, you can use this approach instead:

*[_type == "article" && $slug in categories[]->slug.current] {
    ...,
    categories[]-> {
      title,
      slug
    }  
}

This dereferences all categories in the array and checks if your slug exists in any of them. However, this can be less performant than using references() with the document ID, because it has to dereference every category reference to check the slugs.

The references() function is specifically designed for checking if a document references another document by ID, which is why it's the recommended and most efficient approach when working with reference fields.

Show original thread
7 replies
I would recommend trying out the GROQ query in Vision Plugin first and ensure that it is working.Also, from what I understand variables should be passed in as
params ?
It's just that I don't know if it's possible to do a query to get "article" that have a list "categories" of reference "category" with a slug that match my slug.
I found this to do the match

references("category", "categories[]->slug", $slug)
But it doesn't work in Vision Plugin
I don't know find anything else
Something like this maybe?
*[_type == "article" && categories[]->slug match $slug]{
  title,
  "slug": categories[]->slug,
}
Wow merci
It works with your solution
thanks

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?