Quick Tip: GraphQL Fragments in Gatsby

Joel Turner - Jan 4 '20 - - Dev Community

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
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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
        }
    }
  }
`)
Enter fullscreen mode Exit fullscreen mode

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;
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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
      }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now we can grab that data like this:

const {
    inktober2017: { edges: ink2017Edges = [] } = {},
    inktober2018: { edges: ink2018Edges = [] } = {},
    letterClash: { edges: letterClashEdges = [] } = {},
  } = data
Enter fullscreen mode Exit fullscreen mode

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?

. . . . . . . . . . . . . . . . . .
Terabox Video Player