Skip to content
Sanity
Get started
  • Sanity Studio - Flexible editing environment
  • Content Lake - Real-time database
  • Developer experience - Tooling you love
  • Structured content - The philosophy behind Sanity
  • Review changes - View edits & rollback instantly
  • Image pipeline - On-demand transformations
  • E-commerce - Better shopping experiences
  • Marketing sites - Control your story
  • Products & services - Innovate and automate
  • Mobile apps - Content backend for every OS
  • Aether - Unique digital shopping experience
  • Morning Brew - Omnichannel media distribution
  • InVision - Delivering exceptional customer experiences
  • DataStax - Personalization for global audience
  • React
  • Gatsby
  • Next
  • Nuxt
  • Eleventy
  • Netlify
  • Vercel
  • Algolia
  • Documentation
  • Reference
  • Guides
  • Resource library
  • Headless CMS
  • Tools & plugins
  • Project showcase
  • Schemas & snippets
  • Agency partners
  • Technology partners
  • Get support
  • Share your work
  • 5 Disadvantages Of Wordpress That Are Holding You Back
EnterprisePricing
Contact salesLog inGet started
Published October 29th 2018

3 simple things in GROQ to supercharge your frontends

GROQ is Sanity’s graph-oriented query language. It lets you do rapid development with structured content. As soon as you create a document on the backend, you can instantly query it. Here's 3 simple things you can do in GROQ to get you started.

Knut Melvær

Principal Developer Marketing Manager

GROQ is Sanity’s graph-oriented query language. It lets you do rapid development with structured content. As soon as you create a document on the backend, you can instantly query it. No need to define a schema or write a resolver. You can use it with anything that speaks HTTP, but it also has clients in JavaScript, PHP, and .NET.

A basic query in GROQ looks like this: *[_type == "product"]. You read it like “select everything (*) and filter ([ ]) the selection down to every document whose _type is product. You can get far by just using the filter-capabilities in GROQ. It has many more features that make developing with it fast and convenient. Here’s a handpicked three to get you started.

1. Use projections to get exactly as little as you need

Early in the development stage, it can be useful to fetch complete documents with GROQ, but there comes a time where you want to optimize how much data you’re fetching. Then projections come in handy. You make projections by adding curly braces after the filter’s square braces. The anatomy of a GROQ query looks like this:

*[<filter>]{<projection>}

So if we get all the products with *[_type == "product"] we make the response slimmer by adding a projection to get only the _id and title:

*[_type == "product"]{_id, title}

Outputs:

[
  {
    "_id": "227bbb74-5656-4376-80b3-7424bddc5001",
    "title": "Happy Kitchen - Hamburger"
  },
  {
    "_id": "35f78f0b-8938-412d-aae0-80937ee4a744",
    "title": "Katjes Grün-Ohr Bärchen Gummies"
  },
  {
    "_id": "8a4337ae-4ec8-431f-8890-9e0b0192331a",
    "title": "Snører Lakris"
  }
]

There’s plenty of more things you can do in projections, some of those we’ll come back to in the next sections.

2. Count things!

You can use GROQ to count things. Let’s say you wonder how many products you have:

count(*[_type == "product"])
# outputs
> 11

So you can get all the products, but also have a count ready immediately:

{
  "products": *[_type == "product"],
  "total": count(*[_type == "product"])
}

Yep, this means that you can compose several GROQ-filters (and projections!) in one query. Remember that complexity comes with some cost, but if you use the CDN the queries will be geographically cached .

You can also do maths in GROQ. Say you want to calculate how many products you have available in your store:

{ 
  "availableProducts": count(*[_type == "product"]) - count(*[_type == "product" && soldOut == true]) 
}

Outputs:

{
  "availableProducts": 98
}

3. Save roundtrips by following references

One of the key features of structured content is the ability to make references between documents. When you create a reference, it is stored like this in the document:

{ 
  _id: "1ba26a25-7f35-4d24-804e-09cc76a0cd73",
  //... more data, 
  vendor: { 
    _type: "reference", 
    _ref: "15411164-418a-4f67-ac47-6ba060c61976" 
  }
}

If you’re used to RESTful APIs, you would be inclined to make a new query with the id on the _ref-key (*[_id == "<someOtherId>"]), but no need! You can join on a reference where it occurs by adding a -> in the projection. If you try this out, it can be useful to know about the ... operator, so that you can get the rest of the values without having to specify them:

*[_type == "product"]{
  ...,
  vendor->
}

This query give you the whole referenced vendor document, you can also use projections to get what you need, e.g:

*[_type == "product"]{
  title,
  vendor->{_id, title}
}

Outputs:

{
  "title": "Kit Kat Petit Matcha - Double Berry & Almond",
  "vendor": {
    "_id": "1e6f68d7-10bd-4b83-8880-a0ec0227b725",
    "title": "Nestlè"
  }
}

But there's more…

We have only scratched the surface of what you can do with GROQ. If you want to learn more you should head over to the documentation or join our Slack community and meet a bunch of developers who are using GROQ to do all manner of things.




Page content

  • 1. Use projections to get exactly as little as you need
  • 2. Count things!
  • 3. Save roundtrips by following references
  • But there's more…

Platform

Structured ContentDeveloper experienceContent LakeSanity StudioSecurity & Compliance
  • Sanity vs Contentful
  • Sanity vs Strapi
  • Sanity vs Wordpress
  • Sanity vs Adobe Experience Manager
  • Sanity vs Hygraph
  • Sanity vs Sitecore
  • Sanity vs Storyblok
  • Sanity vs Contentstack
  • Sanity vs Prismic
  • Sanity vs Drupal
  • Sanity vs ButterCMS

Resources

Documentation
  • React Blog
  • Gatsby Blog
  • Next.js Landing Pages
  • Progressive Web Application
  • Single Page Application
  • Svelte & Typescript App
  • Vue & Tailwind Blog
  • Developer Portfolio Templates
  • Form validation with Yup
  • Live Preview with Next.js and Sanity.io
Resource library
  • Agency partners
  • Technology partners
  • Blog Template
  • Personal Website Template
  • Developer Portfolio Templates
  • All Templates
Case Studies
  • Headless CMS
  • What is an API CMS
  • Static Sites 101
  • Headless SEO
  • Localization
  • GraphQL vs REST
  • What is a DXP?
  • Typescript 101
  • Content as a Service
  • Ecommerce SEO
  • React CMS
  • Next.JS CMS
  • CMS for Shopify
  • Content platform
  • Multilingual CMS
  • Static Site CMS
  • Gatsby CMS
  • Node CMS
  • E-commerce CMS
  • Vue CMS
  • Angular CMS
  • GraphQL CMS
  • Newspaper CMS
  • Magazine CMS
  • CMS for apps
  • Remix CMS

Company

Contact SalesEnterpriseCareersTerms of ServiceAccessibility Statement

Stay connected

  • GitHub
  • Slack
  • Twitter
  • YouTube
  • Stack Overflow
  • Blog RSS
  • Newsletter
©Sanity 2023