How to Order and Specifically Select Multiple _Types in a Query
The challenge you're facing is that you need different limits for different document types in a single query. Unfortunately, GROQ doesn't allow you to apply different slice operations ([0...4]) to different document types within a single filter like *[_type in ["hikes", "post"]].
The best solution is to use GROQ's array concatenation operator (+) to combine two separate queries with their own limits and ordering:
*[_type == "hikes"] | order(_createdAt desc) [0...4] {
_createdAt,
body,
mainImage,
number,
people,
slug,
title,
trailHiked -> {
name,
difficulty,
distance,
rating,
trailType,
location
}
} + *[_type == "post"] | order(_createdAt desc) [0] {
title,
body,
mainImage
}The + operator concatenates the results of both queries into a single array. This gives you exactly what you need: the 4 most recent hikes and the 1 most recent post.
Key points:
- Each query can have its own
order()and slice[0...4]or[0] - The
+operator merges the results into one array - You no longer need the conditional projection syntax (
_type == "hikes" => {...}) since each query already filters by type - Make sure to add
| order(_createdAt desc)to each query to get the most recent documents
If you need the results in a specific order (like all hikes first, then the post), the concatenation order controls that. If you want them sorted together by date after merging, you could wrap the whole thing: (*[_type == "hikes"] | order(_createdAt desc) [0...4]{...}) + (*[_type == "post"] | order(_createdAt desc) [0]{...}) | order(_createdAt desc), though this would mix hikes and posts chronologically.
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.