Fragments
A "fragment" is a projection that's reusable. Fragments can be used across multiple queries, and can be easily extended or combined.
A "fragment" is just a useful
GroqDconcept; it is not an actual feature ofGROQ.
Creating Fragments
When creating a fragment, you first specify the type of the fragment, using either q.fragment<T>() or q.fragmentForType<"...">().
Then you call the .project(...) method to select the appropriate fields.  See the Projections documentation for details on this syntax.
q.fragmentForType<"type">()
Creates a fragment for a Document, based on the document type.
const productFragment = q.fragmentForType<"product">().project(sub => ({
  name: q.string(),
  price: q.number(),
  images: sub.field("images[]").deref().project({
    url: q.string(),
  }),
}))
q.fragment<T>()
Creates a fragment for any type you specify. This is useful for inline types that do not have a top-level document type.
const keyValueFragment = q.fragment<{ key: string, value: number }>().project({
  key: q.string(),
  value: q.number(),
})
Using Fragments
Fragments are just plain objects, so they can be passed directly to .project(frag), or they can be spread like .project({ ...frag }).
In a Query
Pass the fragment directly to .project:
q.star.filterByType("product").project(productFragment)
// GROQ: *[_type == "product"]{ 
//   name, 
//   price, 
//   "images": images[]->{ url }
// } 
Or you can spread the fragment to extend it:
q.star.filterByType("product").project(sub => ({
  ...productFragment,
  category: sub.field("category").deref().field("title"),
}))
Extending Fragments
Simply use the "spread" operator inside a projection:
const productDetailsFragment = q.fragmentForType<"product">().project(sub => ({
  ...productFragment,
  category: sub.field("category").deref().field("title"),
}))
Combining Fragments
Multiple fragments can be combined using the spread operator:
const productColors = q.fragmentForType<"product">().project(sub => ({
  colors: sub.field("colors[]").deref().field("name"),
}));
const productWithColors = q.fragmentForType<"product">().project({
  ...productFragment,
  ...productColors,
})
Extracting the Type
It's usually very useful to extract the type of a fragment, so you can consume it in various places.
This can be done via InferFragmentType<typeof frag>:
import { InferFragmentType } from "groqd";
type ProductFragment = InferFragmentType<typeof productFragment>
// { name: string, price: number, images: Array<{ url }> }