We are hiring

Gatsby GraphQL definition in other files

Gatsby is used to build static web sites, following the latest web standards and being performance optimized. Gatsby uses the latest popular technologies including ReactJS, Webpack, ES6+ JS and GraphQL.

GraphQL is a query language for requesting data from an API and it's used in Gatsby components. You don't have to use GraphQL in your components but it offers a few advantages over other methods such as :

  • Retrieving only the data you need.
  • Adding new data types without needing to create a new endpoint.
  • Storing data in any way you want, be it a database, headless CMS or Markdown text files.

Every gatsby component can have a query inside it, but here we are faced with a problem. What happens if you want to query the same data in different components ? Sure you can copy it, but what if you change you data structure ? What if you copied the query to multiple components and lost track ? The solution is using GraphQL fragments.

Fragments are a way to reuse parts of a GraphQL query. It allows you to split up complex queries into reusable pieces. But it's not as simple as creating a new .graphql file and including it to your component.

Let's have a look at a simple query that you would use in your component. This query would reside along with your component, fetch data and make it available to that component.

file: blog.js;
export const query = graphql`
  query($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
        tags
      }
    }
  }
`;

To split the query into a fragment we need to create a new file; let's call it blog-fragment.js. Now Gatsby will automagically run this and make BlogPostQueryFragment fragment available to all other components.

file: blog-fragment.js;
import { graphql } from 'gatsby';

export const BlogPostQueryFragment = graphql`
  fragment BlogPostQueryFragment on Query {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
        tags
      }
    }
  }
`;

To use it we simply just call it like this, no need to include anything.

file: blog.js;
export const query = graphql`
  query($slug: String!) {
    ...BlogPostQueryFragment
  }
`;

With this we can reuse the fragment in other components. You could just as well make a part of a query a fragment and use it with other data types. Extra example using StaticQuery

<StaticQuery
    query={graphql`
      query {
        ...BlogPostQueryFragment
      }
    `}
    render={data => {
      ...
    }}
/>