DEV Community

Cover image for Sanity GROQ for Beginners: 8 Queries You’ll Use on Every Project
Rw Infotech
Rw Infotech

Posted on

Sanity GROQ for Beginners: 8 Queries You’ll Use on Every Project

If you are just starting with Sanity development, the first thing you will meet is GROQ, Sanity's query language. It looks unusual at first, but a handful of patterns cover most of what you will build. Here are eight to learn first.

You can try every query below in the Vision tool inside Sanity Studio, which lets you run GROQ and see the results instantly.

1. Get every document of one type

*[_type == "post"]
Enter fullscreen mode Exit fullscreen mode

* means "all documents," and the square brackets filter them. This returns every document whose type is post.

2. Pick only the fields you need

*[_type == "post"]{ title, publishedAt }
Enter fullscreen mode Exit fullscreen mode

The curly braces are a projection. Ask only for what the page needs, and your responses stay small and fast.

3. Filter by a field

*[_type == "post" && featured == true]
Enter fullscreen mode Exit fullscreen mode

Combine conditions with &&. This example assumes your post type has a boolean field called featured.

4. Fetch a single document by slug

*[_type == "post" && slug.current == $slug][0]
Enter fullscreen mode Exit fullscreen mode

The [0] at the end returns one document instead of a list. $slug is a parameter, so you never build queries by gluing strings together:

const post = await client.fetch(
  `*[_type == "post" && slug.current == $slug][0]`,
  { slug: 'my-first-post' }
)
Enter fullscreen mode Exit fullscreen mode

5. Sort your results

*[_type == "post"] | order(publishedAt desc)
Enter fullscreen mode Exit fullscreen mode

The pipe | sends the results into order(). Use desc for newest first and asc for oldest first.

6. Limit and paginate

*[_type == "post"] | order(publishedAt desc)[0...5]
Enter fullscreen mode Exit fullscreen mode

The slice [0...5] returns the first five items. For pagination, use parameters such as [$start...$end].

7. Follow a reference

*[_type == "post"]{
  title,
  "authorName": author->name
}
Enter fullscreen mode Exit fullscreen mode

The arrow -> follows a reference to another document and lets you read its fields. The quoted name on the left creates a new field in the result.

8. Count documents

count(*[_type == "post"])
Enter fullscreen mode Exit fullscreen mode

Handy for dashboards, pagination totals and quick checks.

Bonus patterns

*[_type == "post" && defined(publishedAt)]
*[_type == "post" && title match "sanity*"]
*[_type == "post" && references($authorId)]
Enter fullscreen mode Exit fullscreen mode
  • defined() checks that a field has a value, which is useful for hiding unfinished drafts.
  • match does simple text matching.
  • references() finds every document that points to a given document.

Final thoughts

GROQ rewards a small amount of practice. Start with filters and projections, add ordering and slicing, then move on to references. Keep your queries lean, ask only for the fields you need, and your pages will stay fast as your content grows.

What GROQ pattern do you reach for most? Share it in the comments.

Top comments (0)