CoursesContent-driven web application foundationsQuery content with GROQ
Track
Work-ready Next.js

Content-driven web application foundations

Log in to watch a video walkthrough of this lesson
Video thumbnail

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 likely 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 perhaps 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}
  • *: Represents all documents in a dataset as an array
  • [_type == "post"] represents a filter where you narrow down those documents
  • { title } represents a projection where you define which attribute in those matching documents you want the query to return

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 type post that have a slug. From each document, it will return the _id, title and slug attributes.
    • This can be used on a "posts index" page to show the latest posts.
  • POST_QUERY will return only one post type of document where the value the slug matches a passed-in variable $slug. From this document, it will return the title, body and mainImage 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/draft documents when using the default perspective – raw.

The Sanity Client on your front end is not authenticated, so it only fetches 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.

Courses in the "Work-ready Next.js" track