Gatsy page query fails to work when using named export at the end of the page. Why?

Viewed 315

I have the following page template in Gatsby.

import React from 'react';
import { graphql } from 'gatsby';
import Layout from '../components/layout';

const PageTemplate = props => {
  const { wordpressPage: currentPage } = props.data;
  return (
    <Layout>
      <h1 dangerouslySetInnerHTML={{ __html: currentPage.title }} />
      <div dangerouslySetInnerHTML={{ __html: currentPage.content }} />
    </Layout>
  );
};

export const pageQuery = graphql`
  query($id: String!) {
    wordpressPage(id: { eq: $id }) {
      title
      content
      date(formatString: "MMMM DD, YYYY")
    }
    site {
      id
      siteMetadata {
        title
      }
    }
  }
`;

export default PageTemplate;

Which works as expected (taken from tutorial), however I tend to prefer to do all my exporting at the end of the page like so:

import React from 'react';
import { graphql } from 'gatsby';
import Layout from '../components/layout';

const PageTemplate = props => {
  const { wordpressPage: currentPage } = props.data;
  return (
    <Layout>
      <h1 dangerouslySetInnerHTML={{ __html: currentPage.title }} />
      <div dangerouslySetInnerHTML={{ __html: currentPage.content }} />
    </Layout>
  );
};

const pageQuery = graphql`
  query($id: String!) {
    wordpressPage(id: { eq: $id }) {
      title
      content
      date(formatString: "MMMM DD, YYYY")
    }
    site {
      id
      siteMetadata {
        title
      }
    }
  }
`;

export default PageTemplate;
export { pageQuery }

However this fails to work - props.data is undefined. It's a subtle difference but why would this cause the pageQuery to not execute?

2 Answers

I believe pageQuery has to be exported before PageTemplate because it is used by it: that's where it gets its props.data from, which explains why you are getting undefined when exporting it after.

This answer is an additional explanation to @hexangel616 who mentioned the order of exports matters:

I believe pageQuery has to be exported before PageTemplate because it is used by it.

Your exported GraphQL queries have a special role in the gatsby build process. From the docs:

At a high level, what happens during the whole bootstrap and build process is:

  1. Node objects are sourced from whatever sources you defined in gatsby-config.js with plugins as well as in your gatsby-node.js file

  2. A schema is inferred from the Node objects

  3. Pages are created based off JavaScript components in your site or in installed themes

  4. GraphQL queries are extracted and run to provide data for all pages

  5. Static files are created and bundled in the public directory

TLDR: In order for gatsby to build properly all your graphql exports have to be in order.

Related