Get all articles in a category for archive page

12 replies
Last updated: Jul 30, 2022
been searching through slack and trying to follow the Groq cheat sheet, but not finding what i need. can someone help?
i want to get all
articles
in a
category
. what's the best way to do so?
i'm trying to create a category archive page for each category
AI Update

Perfect! I found exactly what you need. When you want to get all articles in a category for creating category archive pages, you'll use the in operator in GROQ to filter by reference fields.

Here are the two main patterns depending on how your schema is set up:

If category is an array of references

This is the most common setup where your articles have a categories field that references category documents:

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

You'd pass in the category slug as a parameter:

{
  "categorySlug": "technology"
}

If category is a single reference

If each article only has one category reference:

*[_type == "article" && category->slug.current == $categorySlug] {
  _id,
  title,
  slug,
  category-> {
    title,
    slug
  }
}

The key syntax explained

  • The in operator checks if a value exists in an array
  • categories[]-> follows the reference and gets the actual category documents
  • slug.current accesses the slug field from those referenced documents
  • The -> operator is how you dereference (follow) references in GROQ

For your category archive page

You'll likely want to order and paginate results too:

*[_type == "article" && $categorySlug in categories[]->slug.current] | order(publishedAt desc) [0...12] {
  _id,
  title,
  slug,
  publishedAt,
  excerpt,
  mainImage,
  categories[]-> {
    title,
    slug
  }
}

This gets the first 12 articles in a category, ordered by publish date. You can adjust the slice [0...12] for pagination.

The Sanity recipe on filtering by category has more examples if you need to handle inline arrays or other variations!

Show original thread
12 replies
ok, i've got this going right now

*[_type == 'category']{
  slug,
  'relatedArticles': *[_type == 'article' && references(^._id)]{slug}
}
this returns all the articles for each category...

guess i'm now not sure what to do with this, as i want to build a page for each category, with its articles

so not sure if this is a correct query still
ok, got it sorted ... for anyone looking to do the same, I just had to adjust my
.map
on my archive page.

{post.relatedArticles.map((article) => <PostEntry article={article} />)}

I also had to add
categories[] ->
in order to resolve them deeper down my component pipeline.
final query looked like this.


export const allCategoryPostsQuery = `*[_type == 'category']{slug, 'relatedArticles': *[_type == 'article' && references(^._id)]{..., country ->, categories[] ->}}`
oh, i should add, that i'll also need to include some ordering to get them to list chronologically 😉
Is it also possible to do a dynamic route approach and grab the category name from the address and use it slug style fed as param to the query? Not sure what your front end is.
You can add the order() function to the subquery as well.


export const allCategoryPostsQuery = `*[_type == 'category']{slug, 'relatedArticles': *[_type == 'article' && references(^._id)]order(publishedAt desc){..., country ->, categories[] ->}}`
update: yes
user Y
I did that, and all added a spread for all content from the
category
user S
the front-end is Astro, and it is a dynamic route... that's why this query was so difficult for me to wrap my head around...
first i had to create the routes for all the
category
archive pages, and then i wanted to populate them with the appropriate articles
here's an updated "final" query

export const allCategoryPostsQuery = `*[_type == 'category']{..., 'relatedArticles': *[_type == 'article' && references(^._id)]{..., country ->, categories[] ->} | order(publishDate desc)}`
Btw. If you want to constrain it to references only coming from the categories array, you can do:

“relatedArticles”: *[_type == “article” && ^._id in categories[]._ref]order(publishedAt desc){ _id, title, slug, categories[]->{_id,title,slug}}
Give the use case
references
will unlikely have false positives, but now you know of this pattern as well.
Btw. I'd be a bit careful with the spread when you use it with next. You end up fetching a lot of data you probably never use and that get stored in the json files next generates. Even though it's gzipped text it's something to consider.
user Y
that's a good shout! i'm using Astro, but regardless of framework, querying for only what you need is always best

👍

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?