Fragments are reusable units in GraphQL that allow you to construct sets of fields and reuse them across multiple queries and mutations.
Fragments let you define a set of fields once and reuse them in multiple places. This is particularly useful when you need to fetch the same fields from the same type in different queries.
fragment FragmentName on TypeName {
field1
field2
field3
}fragment ProductDetails on ProductInterface {
id
sku
name
price {
regularPrice {
amount {
value
currency
}
}
}
image {
url
label
}
}
# Using the fragment in a query
query GetProducts {
products(filter: { category_id: { eq: "3" } }) {
items {
...ProductDetails
}
}
}fragment AddressDetails on CustomerAddress {
id
firstname
lastname
street
city
region {
region_code
region
}
postcode
country_code
telephone
}
query GetCustomerAddresses {
customer {
addresses {
...AddressDetails
}
default_shipping {
...AddressDetails
}
default_billing {
...AddressDetails
}
}
}fragment PriceInfo on ProductPrice {
regularPrice {
amount {
value
currency
}
}
finalPrice {
amount {
value
currency
}
}
discount {
amount_off
percent_off
}
}
query GetProductWithPrice($sku: String!) {
products(filter: { sku: { eq: $sku } }) {
items {
name
sku
price_range {
minimum_price {
...PriceInfo
}
maximum_price {
...PriceInfo
}
}
}
}
}Fragments can include other fragments:
fragment MediaGallery on ProductInterface {
media_gallery {
url
label
position
}
}
fragment FullProductDetails on ProductInterface {
id
sku
name
description {
html
}
...MediaGallery
price_range {
minimum_price {
...PriceInfo
}
}
}Use inline fragments when working with interfaces or unions:
query GetProducts {
products(filter: { sku: { eq: "24-MB01" } }) {
items {
id
sku
name
... on ConfigurableProduct {
configurable_options {
id
label
values {
value_index
label
}
}
}
... on BundleProduct {
items {
title
options {
label
quantity
}
}
}
}
}
}# Without fragments (repetitive)
query GetMultipleProducts {
product1: products(filter: { sku: { eq: "SKU1" } }) {
items {
id
sku
name
price { regularPrice { amount { value } } }
}
}
product2: products(filter: { sku: { eq: "SKU2" } }) {
items {
id
sku
name
price { regularPrice { amount { value } } }
}
}
}
# With fragments (DRY principle)
fragment BasicProduct on ProductInterface {
id
sku
name
price { regularPrice { amount { value } } }
}
query GetMultipleProducts {
product1: products(filter: { sku: { eq: "SKU1" } }) {
items {
...BasicProduct
}
}
product2: products(filter: { sku: { eq: "SKU2" } }) {
items {
...BasicProduct
}
}
}Fragments ensure that the same fields are requested across different parts of your application.
Update fields in one place (the fragment) instead of multiple queries.
Fragments can access query variables:
fragment ProductList on Products {
items {
id
sku
name
}
page_info {
page_size
current_page
total_pages
}
}
query GetProducts($pageSize: Int = 20, $currentPage: Int = 1) {
products(
filter: { category_id: { eq: "3" } }
pageSize: $pageSize
currentPage: $currentPage
) {
...ProductList
}
}fragment MoneyFields on Money {
value
currency
}
fragment CartPriceFields on CartPrices {
grand_total {
...MoneyFields
}
subtotal_excluding_tax {
...MoneyFields
}
subtotal_including_tax {
...MoneyFields
}
}
fragment CartItemFields on CartItemInterface {
id
quantity
product {
name
sku
}
prices {
price {
...MoneyFields
}
row_total {
...MoneyFields
}
}
}
fragment CartFields on Cart {
id
email
total_quantity
items {
...CartItemFields
}
prices {
...CartPriceFields
}
}
query GetCart($cartId: String!) {
cart(cart_id: $cartId) {
...CartFields
}
}
mutation AddToCart($cartId: String!, $sku: String!, $quantity: Float!) {
addSimpleProductsToCart(
input: {
cart_id: $cartId
cart_items: [{ data: { sku: $sku, quantity: $quantity } }]
}
) {
cart {
...CartFields
}
}
}# Good
fragment ProductBasicInfo on ProductInterface { ... }
fragment ProductPricingInfo on ProductInterface { ... }
fragment ProductMediaGallery on ProductInterface { ... }
# Bad
fragment Fragment1 on ProductInterface { ... }
fragment Data on ProductInterface { ... }# Good - focused fragments
fragment ProductIdentity on ProductInterface {
id
sku
name
}
fragment ProductPricing on ProductInterface {
price_range {
minimum_price {
regular_price { value currency }
}
}
}
# Bad - too many unrelated fields
fragment Everything on ProductInterface {
id
sku
name
price_range { ... }
description { ... }
media_gallery { ... }
related_products { ... }
# Too much in one fragment
}fragment ProductCore on ProductInterface {
id
sku
name
}
fragment ProductDisplay on ProductInterface {
...ProductCore
image {
url
label
}
small_image {
url
label
}
}
fragment ProductFull on ProductInterface {
...ProductDisplay
description {
html
}
short_description {
html
}
media_gallery {
url
label
}
}// ProductCard.jsx
import { gql } from '@apollo/client';
const PRODUCT_CARD_FRAGMENT = gql`
fragment ProductCard on ProductInterface {
id
sku
name
price_range {
minimum_price {
regular_price {
value
currency
}
}
}
image {
url
label
}
}
`;
export { PRODUCT_CARD_FRAGMENT };Fragments must be defined on a specific type:
# Valid - fragment on interface
fragment ProductFields on ProductInterface {
id
sku
name
}
# Valid - fragment on concrete type
fragment SimpleProductFields on SimpleProduct {
id
sku
name
}
# Usage with type checking
query GetProduct($sku: String!) {
products(filter: { sku: { eq: $sku } }) {
items {
...ProductFields
... on SimpleProduct {
...SimpleProductFields
}
... on ConfigurableProduct {
configurable_options {
id
label
}
}
}
}
}fragment PLPProduct on ProductInterface {
id
sku
name
url_key
small_image {
url
}
price_range {
minimum_price {
regular_price {
value
currency
}
final_price {
value
}
}
}
}fragment PDPProduct on ProductInterface {
id
sku
name
description {
html
}
media_gallery {
url
label
}
price_range {
minimum_price {
regular_price {
value
currency
}
}
}
... on ConfigurableProduct {
configurable_options {
id
label
values {
value_index
label
swatch_data {
value
}
}
}
}
}fragment CheckoutAddress on CartAddressInterface {
firstname
lastname
street
city
region {
code
label
}
postcode
country {
code
label
}
telephone
}
fragment CheckoutCart on Cart {
id
email
billing_address {
...CheckoutAddress
}
shipping_addresses {
...CheckoutAddress
selected_shipping_method {
carrier_code
method_code
amount {
value
currency
}
}
}
}# Error: Fragment "ProductDetails" not found
query GetProducts {
products {
items {
...ProductDetails # Fragment not defined
}
}
}
# Solution: Define the fragment
fragment ProductDetails on ProductInterface {
id
sku
name
}
query GetProducts {
products {
items {
...ProductDetails
}
}
}# Error: Fragment cannot be spread here
fragment CustomerFields on Customer {
firstname
lastname
}
query GetProducts {
products {
items {
...CustomerFields # Wrong type!
}
}
}
# Solution: Use correct type
fragment ProductFields on ProductInterface {
name
sku
}
query GetProducts {
products {
items {
...ProductFields
}
}
}- Don't over-fetch: Include only necessary fields in fragments
- Avoid deep nesting: Keep fragment depth reasonable
- Reuse wisely: Balance reusability with specificity
- Monitor query size: Large fragments can create heavy queries
← Previous: Using Variables | Back to Getting Started | Next: Architecture →