Lesson
5
Query content with GROQ
Organize and author queries for your content with best-practice conventions.
Log in to mark your progress for each Lesson and Task
If you're new to Sanity, you're probably new to GROQ. It's an incredibly powerful way to query content, and thankfully, it's quick to get started with.
You'll only need to know the basics of writing queries for now. However, it is beneficial to learn GROQ when working with Sanity as it powers queries, GROQ-powered webhooks and content permissions when configuring Roles.
This lesson is focused on writing basic GROQ queries to serve our Next.js application. Future lessons will expand on these queries.
See Between GROQ and a hard place for more thorough lessons on how to write expressive queries with GROQ.
The Query Cheat Sheet - GROQ is the most popular resource for quickly finding useful query examples.
Sanity content is typically queried with GROQ queries from a configured Sanity Client. Sanity also supports GraphQL. You may prefer to use GraphQL in your application, but these courses will focus on querying with Sanity Client and GROQ.
You can break up most GROQ queries into three key parts.
Consider this query:
*[_type == "post"]{title}
*
: returns all documents in a dataset as an array[_type == "post"]
represents a filter where you narrow down the proceeding array{ title }
represents a projection where you define which attributes in those array items you want to return in the response
next-sanity
exports the defineQuery
function which will give you syntax highlighting in VS Code with the Sanity extension installed.
Install the Sanity VS Code extension if this is the IDE you are using.
The defineQuery
function also has another important role, Sanity TypeGen searches for variables that use it to generate Types for query results.
For convenience and organization, you'll write all queries inside a dedicated file in your project.
Create a file to store two basic GROQ queries:
src/sanity/lib/queries.ts
import {defineQuery} from 'next-sanity'
export const POSTS_QUERY = defineQuery(`*[_type == "post" && defined(slug.current)][0...12]{ _id, title, slug}`)
export const POST_QUERY = defineQuery(`*[_type == "post" && slug.current == $slug][0]{ title, body, mainImage}`)
POSTS_QUERY
will return an array of up to 12 published documents of the typepost
that have a slug. From each document, it will return the_id
,title
andslug
attributes.- This can be used on a "posts index" page to show the latest posts.
POST_QUERY
filters down topost
documents of the post type where the value theslug
matches a passed-in variable$slug
. Only one document is returned because of the[0]
filter. From this one document, it will return thetitle
,body
andmainImage
attributes.
Before using these queries in your front end, it's possible to test them at any time from within your Sanity Studio using the Vision tool.
Open http://localhost:3000/studio/vision, paste the
POSTS_QUERY
GROQ query string and click Fetch*[_type == "post" && defined(slug.current)][0...12]{ _id, title, slug}
You should see up to 12 items in the "result" panel.
Queries fetched in Vision use the same user authentication that the Studio does. So it will return private documents when using the default perspective – raw
.
In a public dataset, a document is private if it has a period "
.
" in the _id
, such as { _id: "drafts.asdf-1234" }
and can only be queried by an authenticated request. In a private dataset all documents are private.The Sanity Client for your front end is not authenticated (unless you give it token
) so it will only return publicly visible documents in a public dataset.
See Datasets for more information about Public and Private datasets.
Perspectives for Content Lake determine whether published or draft documents are returned in the response.
Now that you've proven that your GROQ queries get results, let's automatically generate TypeScript types for these responses.
You have 3 uncompleted tasks in this lesson
0 of 3