GraphQL Fragments, Built Live

A GraphQL fragment is a named, reusable set of fields for one type, written as fragment Name on Type and pulled into a query with ...Name. An inline fragment, written ... on Type, has no name and picks fields only when the result is that concrete type, which is how you query unions and interfaces.

Fragment forms
FormSyntaxUse it for
Named fragmentfragment UserCard on User { ... }Sharing one field list across queries
Spread...UserCardIncluding a named fragment's fields
Inline fragment... on Photo { url }Fields of one member of a union or interface
Inline without type... @include(if: $full) { bio }Applying a directive to a group of fields
Type name__typenameTelling union members apart in the response

Updated

Tick the fields you want in the builder and it writes the query for you, once with a named fragment and once with the fields typed inline, so you can see they ask for the same data. Turn on the search results option to add inline fragments over a union.

Fragment query builder

query Profile($id: ID!) {
  user(id: $id) {
    ...UserCard
  }
}

fragment UserCard on User {
  id
  name
  avatarUrl
}

Schema used by the builder

A union for search results

SearchResult can be a User or a Photo, so a selection on it needs inline fragments to reach fields of either member.

type User {
  id: ID!
  name: String!
  avatarUrl: String
  email: String
  createdAt: String!
}

type Photo {
  id: ID!
  url: String!
  width: Int!
}

union SearchResult = User | Photo

type Query {
  user(id: ID!): User
  search(text: String!): [SearchResult!]!
}

Reading a union response

What the search returns

Each item carries only the fields of its own branch, plus __typename.

{
  "data": {
    "search": [
      { "__typename": "User", "id": "42", "name": "Ada" },
      { "__typename": "Photo", "url": "/p/lake.jpg", "width": 1200 }
    ]
  }
}

Branching on __typename

The type name is the safe way to tell the members apart; checking for a field can break when a type later gains it.

for (const item of data.search) {
  switch (item.__typename) {
    case "User":
      renderUser(item);
      break;
    case "Photo":
      renderPhoto(item);
      break;
  }
}

Named fragments for reuse

Suppose a profile header, a comment and a member list all show a name and an avatar. Typing those fields three times invites drift: one copy gains a field the others lack. A fragment on User holds the list once and each query spreads it.

Component-based apps take this further. Each component declares the fragment it needs, and the page query spreads the fragments of the components it renders, so data needs live beside the code that uses them.

Inline fragments and type conditions

The on Type part is the type condition. For a named fragment it says which type the fields belong to. For an inline fragment inside a union field, it makes those fields apply only when the object is that type.

A search that returns users, posts and photos is the classic case. The selection lists ... on User, ... on Post and ... on Photo, each with its own fields, and __typename tells the client which branch each result took.

How it works

  1. Tick the User fields the card on your screen shows.
  2. Choose whether the fields go into a named fragment or straight into the query.
  3. Turn on search results to add a union field with an inline fragment per member type.
  4. Copy the query and run it against a schema that has these types.

Tips

Frequently asked questions

Do fragments make responses smaller?

No. A fragment is a writing aid for the query. The server expands it, and the response looks exactly as if you had typed the fields out. If two spreads select the same field, it appears once.

When must I use an inline fragment?

When a field returns a union or an interface and you need fields that only some member types have. graphql.org shows this with a hero that may be a Droid with primaryFunction or a Human with height.

Can a fragment be used on a different type?

Only where it could apply. A fragment on an interface can be spread inside any object type that implements it, but a fragment on User spread inside a Post selection fails validation.

Where do fragments live in the document?

At the top level of the document, next to the operations, in any order. Every fragment defined must be used, or the server rejects the document as invalid.

Related: GraphQL vs REST, GraphQL mutations, GraphQL subscriptions, JavaScript async and fetch.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap