Quick Tip: GraphQL Fragments in Gatsby
Joel Turner
Posted on January 4, 2020
GraphQL makes it easy to get exactly the data we need for a given component. There are many times when we end up using the same query or part of a query in multiple places. This is where GraphQL Fragments can help us.
To declare a fragment we can add fragment MyAwesomeFragment on BlogPost
. The keyword fragment
tells GraphQL that we're creating the fragment with the name, MyAwesomeFragment
. And all of this is on the type BlogPost
.
On joelmturner.com, I have a few different places where I'm querying images for galleries. So instead of repeating the whole query in every variation across the site I can create a queries file and drop the repeated parts in there. Here's an example of that in action.
fragment InstaNodes on InstagramContentEdge {
node {
id
localImage {
childImageSharp {
fluid(maxWidth: 1248, maxHeight: 1248) {
...GatsbyImageSharpFluid
}
}
}
images {
standard_resolution {
width
height
url
}
}
}
}
Then we can use them in our components with a page query or static query.
const data = useStaticQuery(graphql`
query {
allInstagramContent(
filter: { tags: { glob: "ink*2017" } },
sort: { fields: created_time, order: ASC }) {
edges {
...InstaNodes
}
}
}
`)
Typing
If you're using TypeScript you can also drop the types for the fragments in the queries file so they're all together.
type IInstaNodes = {
node: {
id: string;
localImage: {
childImageSharp: {
fluid: FluidObject;
}
}
images: {
standard_resolution: {
width: number;
height: number;
url: string;
}
}
}
}
Bonus
Add an alias if you're doing similar top-level requests. Here's an example of my Instagram requests.
fragment inktober2017 on Query {
inktober2017: allInstagramContent(
filter: { tags: { glob: "ink*2017" } }
sort: { fields: created_time, order: ASC } ) {
edges {
...InstaNodes
}
}
}
fragment inktober2018 on Query {
inktober2018: allInstagramContent(
filter: { tags: { glob: "ink*2018" } }
sort: { fields: created_time, order: ASC } ) {
edges {
...InstaNodes
}
}
}
fragment letterClash on Query {
letterClash: allInstagramContent(
filter: { tags: { eq: "letterclash" } }
sort: { fields: created_time, order: ASC } ) {
edges {
...InstaNodes
}
}
}
Now we can grab that data like this:
const {
inktober2017: { edges: ink2017Edges = [] } = {},
inktober2018: { edges: ink2018Edges = [] } = {},
letterClash: { edges: letterClashEdges = [] } = {},
} = data
You can see the result of this on my illustration page. Are you using graphql fragments or aliases? If so, how are they working for you?
Posted on January 4, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.