How a GROQ query works
Read a query from left to right. Take *[_type == "post"]{title, "author": author->name} as an example.
*returns every document in the dataset the current user is allowed to read.A filter in square brackets keeps only the documents for which its expression is true. Here it keeps documents of type
post.A projection in curly braces shapes the result; without one, the query returns all data of each document.
The
->operator follows a reference and puts the referenced document's content into the result, which is how GROQ does joins.
To sort results, add order(), which sorts ascending unless you add desc to a field. Queries can take parameters written with a $ prefix, passed as URL parameters on the HTTP API. A perspective (for example published, drafts or raw) decides which version of a document a GROQ query returns. Draft and release versions only come back for authenticated requests, so draft queries need a read token on the server. Sanity's guide to how queries work covers each step in more detail.
Key features and limits
JSON compatibility. GROQ syntax is a superset of JSON, so any valid JSON value is also a valid GROQ query.
Functions. GROQ ships built-in functions such as
count(),order()andreferences(). You can define custom GROQ functions, but they cannot recurse, read the parent scope or take more than one parameter.Request size. GET requests to the Query API are capped at 11 KB; longer queries must be sent as POST.
Missing documents. A query for a missing document still returns a value such as
[]ornull, never a 404.Testing. The Vision plugin adds a GROQ playground inside Sanity Studio for testing queries.
Filter and projection settings. In Functions and webhooks you set the GROQ filter and projection as two separate settings.
For the rest of the CMS around the query layer, read what Sanity is and how it works. To weigh Sanity against another headless CMS, see Sanity vs Contentful.
A GROQ rule Pagepro applies on public sites
On Next.js and Sanity builds, Pagepro sends public GROQ queries without a token. When a request carries a token, the Sanity client routes the request to the uncached live API instead of the API CDN, so every render pays for an origin query. The read token stays on a separate preview client, and our Sanity development audits check public queries for tokens.
Sources
- GROQ introductionSanity · sanity.io
- GROQ syntaxSanity · sanity.io
- GROQ specification (sanity-io/groq README)Sanity · github.com
- How GROQ queries workSanity · sanity.io
- Query API referenceSanity · sanity.io