Skip to content

fragment.graphql

GraphQL fragment files contain reusable field selections that can be shared across multiple queries.

src/graphql/fragments/{name}.fragment.graphql
src/graphql/fragments/{name}.fragment.cms.graphql

Shared fragments are located in the central src/graphql/fragments/ directory.

Examples:

src/graphql/fragments/imageProps.fragment.graphql
src/graphql/fragments/articleListItem.fragment.cms.graphql
src/graphql/fragments/authorBio.fragment.graphql
src/graphql/fragments/placeCard.fragment.graphql

In rare cases, component-specific fragments can be colocated:

src/components/{feature}/graphql/{name}.fragment.graphql
fragment {EntityName}{Purpose} on {Type} {
# fields
}

Examples:

fragment ImageProperties on Image { }
fragment ArticleListItem on Article { }
fragment PlaceCard on Place { }
fragment AuthorBio on Author { }
src/graphql/fragments/imageProps.fragment.graphql
fragment ImageProperties on Image {
url
width
height
description # Used as alt text
title
}
src/graphql/fragments/articleListItem.fragment.cms.graphql
#import "#graphql/fragments/imageProps.fragment.graphql"
fragment ArticleListItem on Article {
title
slug
excerpt
publishDate
# Nested fragment
featuredImage {
...ImageProperties
}
# Author info
author {
firstName
lastName
slug
image {
...ImageProperties
}
}
# Metadata
metadata {
category
tags
readTime
}
}
src/graphql/fragments/contentBlock.fragment.graphql
fragment ContentBlock on ContentBlockUnion {
__typename
... on ContentText {
text
format
}
... on ContentImage {
image {
...ImageProperties
}
caption
}
... on ContentVideo {
videoUrl
thumbnail {
...ImageProperties
}
}
}

Use path aliases for fragment imports:

#import "#graphql/fragments/imageProps.fragment.graphql"
#import "#graphql/fragments/authorBio.fragment.graphql"
fragment ArticleDetail on Article {
title
featuredImage {
...ImageProperties
}
author {
...AuthorBio
}
}
src/pages/articles/_graphql/page.query.cms.graphql
#import "#graphql/fragments/articleListItem.fragment.graphql"
query ArticlesPage {
articleCollection(limit: 20) {
items {
...ArticleListItem
}
}
featuredArticles: articleCollection(
where: { featured: true }
limit: 3
) {
items {
...ArticleListItem
}
}
}
fragment ImageProperties on Image {
url
width
height
description # alt text
title
contentType
}
fragment CTAProperties on CTA {
text
url
variant # primary, secondary, text
external
openInNewTab
}
#import "#graphql/fragments/imageProps.fragment.graphql"
fragment AuthorBio on Author {
firstName
lastName
slug
bio
image {
...ImageProperties
}
socialMedia {
twitter
instagram
}
}
#import "#graphql/fragments/imageProps.fragment.graphql"
fragment ArticleCard on Article {
title
slug
excerpt
publishDate
category
image {
...ImageProperties
}
author {
firstName
lastName
}
}
fragment PlaceCard on Place {
name
slug
description
location {
city
country
}
image {
...ImageProperties
}
rating
}

Fragments generate TypeScript types:

fragment ArticleListItem on Article {
title
slug
}

Generates:

// Generated type
export type ArticleListItemFragment = {
__typename?: 'Article';
title: string;
slug: string;
};
// Usage in code
import type { ArticleListItemFragment } from "#graphql/generated/contentful/schema";
function renderArticle(article: ArticleListItemFragment) {
return `<h2>${article.title}</h2>`;
}