Gatsby: v2: Uncaught (in promise) ReferenceError: graphql is not defined

Created on 15 Jul 2018  Â·  14Comments  Â·  Source: gatsbyjs/gatsby

Description

In the process of moving from Gatsby v1 to v2, I converted /src/layouts/index.js to a regular component at /src/components/layout.js. I now get the error

Uncaught (in promise) ReferenceError: graphql is not defined
  at Module.eval (/src/components/Layout.js:53)

Steps to reproduce

Not sure.

Expected result

Site compiles and appears the same as before.

Actual result

Site compiles but <div id="___gatsby"></div> has no children.

Environment

System:
OS: macOS High Sierra 10.13.6
CPU: x64 Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
Shell: 5.3 - /bin/zsh
Binaries:
Node: 10.2.1 - ~/.nvm/versions/node/v10.2.1/bin/node
Yarn: 1.7.0 - /usr/local/bin/yarn
npm: 5.6.0 - ~/.nvm/versions/node/v10.2.1/bin/npm
Browsers:
Chrome: 67.0.3396.99
Safari: 11.1.2
npmPackages:
gatsby: ^2.0.0-beta.37 => 2.0.0-beta.37
gatsby-plugin-catch-links: next => 2.0.2-beta.2
gatsby-plugin-favicon: 2.1.1 => 2.1.1
gatsby-plugin-google-analytics: next => 2.0.0-beta.2
gatsby-plugin-manifest: next => 2.0.2-beta.2
gatsby-plugin-offline: next => 2.0.0-beta.3
gatsby-plugin-react-helmet: next => 3.0.0-beta.3
gatsby-plugin-styled-components: next => 3.0.0-beta.2
gatsby-plugin-typography: next => 2.2.0-beta.2
gatsby-remark-images-contentful: next => 2.0.0-beta.2
gatsby-remark-smartypants: next => 2.0.0-beta.2
gatsby-source-contentful: next => 2.0.1-beta.13
gatsby-transformer-remark: next => 2.1.1-beta.3
npmGlobalPackages:
gatsby-cli: 2.0.0-beta.6

File contents

This is what /src/components/layout.js looks like

import React, { Fragment } from 'react'
import { StaticQuery, graphql } from 'gatsby'
import styled, { ThemeProvider, injectGlobal } from 'styled-components'

import Header from './Header'
import Footer from './Footer'
import theme from '../utils/theme'
import background from '../assets/background.jpg'

injectGlobal`
  body {
    background: url(${background}) no-repeat center center fixed; 
    background-size: cover;
    color: ${props => props.theme.mainWhite};
  }
  #___gatsby {
    height: 100vh;
    display: grid;
    grid-template-rows: auto 1fr auto;
    background: rgba(0, 0, 0, 0.3);
  }
`

const Content = styled.main`
  display: grid;
  grid-template-rows: auto 1fr;
`

const render = (children) => ({ header, footer, site }) => (
  <ThemeProvider theme={theme}>
    <Fragment>
      <Header meta={site.meta} header={header.data} />
      <Content>{children}</Content>
      <Footer footer={footer.data} />
    </Fragment>
  </ThemeProvider>
)

export const siteMetaQuery = graphql`
  fragment siteMetaQuery on RootQueryType {
    site {
      meta: siteMetadata {
        title
        url: siteUrl
      }
    }
  }
`

const query = graphql`
  {
    ...siteMetaQuery
    header: contentfulJson(title: {eq: "Header"}) {
      data {
        external {
          googleScholar
        }
        nav {
          url
          title
        }
      }
    }
    footer: contentfulJson(title: {eq: "Footer"}) {
      data {
        copyright
        links {
          url
          title
        }
        author
      }
    }
  }
`

const Layout = ({ children }) => (
  <StaticQuery query={query} render={render(children)} />
)

export default Layout
help wanted bug

Most helpful comment

Update - I didn't realize this error was shown in browser console - so we don't handle double graphql exports:
https://github.com/JanoshRiebesell/ocean-artup/blob/8e83a10cbadb80b2c1feb52e1793153bed3f50b0/src/templates/page.js#L25-L51

joining them together does fix that error

export const pageQuery = graphql`
  fragment siteMetaQuery on RootQueryType {
    site {
      meta: siteMetadata {
        title
        url: siteUrl
      }
    }
  }
  query($slug: String!) {
    ...siteMetaQuery
    page: contentfulPage(slug: {eq: $slug}) {
      title
      subtitle
      slug
      body {
        data: childMarkdownRemark {
          excerpt
          html
        }
      }
    }
  }
`

seems like babel-plugin-remove-graphql-queries only removes one graphql export - does that sounds right?

All 14 comments

Currently StaticQuery doesn't work if your query isn't defined inline. This is something we want to fix sooner than later but for now, try moving the query inline.

@KyleAMathews Still same problem. I tried inlining render and the siteMetaQuery fragment as well but the error persists.

Are you using graphql anywhere else? Make sure you only use it in StaticQuery. Our Babel code actually removes the graphql query from your code so if it's used elsewhere it'll error.

@KyleAMathews Not in any other files in /src/components if that's what you mean.

I do use it in gatsby-node.js and all my pages and templates, of course. In the latter two, I import it via import { graphql } from 'gatsby'. Isn't that how it's supposed to work?

No in your layout component. Could you post the current state of it here? Also/or is your site open source so I could look at it?

Also/or is your site open source so I could look at it?

It is now.

Hmm, I cloned your repo, installed deps, run gatsby develop and I'm not getting this error

--edit:
nvm - check next comment

Update - I didn't realize this error was shown in browser console - so we don't handle double graphql exports:
https://github.com/JanoshRiebesell/ocean-artup/blob/8e83a10cbadb80b2c1feb52e1793153bed3f50b0/src/templates/page.js#L25-L51

joining them together does fix that error

export const pageQuery = graphql`
  fragment siteMetaQuery on RootQueryType {
    site {
      meta: siteMetadata {
        title
        url: siteUrl
      }
    }
  }
  query($slug: String!) {
    ...siteMetaQuery
    page: contentfulPage(slug: {eq: $slug}) {
      title
      subtitle
      slug
      body {
        data: childMarkdownRemark {
          excerpt
          html
        }
      }
    }
  }
`

seems like babel-plugin-remove-graphql-queries only removes one graphql export - does that sounds right?

Yeah, I checked it after my initial comment - check my previous comment - changing templates/pages like that fixes that error, but then there are some seemingly unrelated errors like:

Warning: Failed prop type: Invalid prop `activeClassName` of type `boolean` supplied to `GatsbyLink`, expected `string`.
Uncaught TypeError: Cannot read property 'map' of undefined

but graphql is not defined is "fixed"

@pieh Thanks for the tip! That indeed solved the problem.

@KyleAMathews @jquense What should be expected behaviour when file has more than one gatsby graphql export? I think we should handle it fine as long as we have only one query, right?

We should remove all of them I think, I believe the query parser handles multiple per fine just fine so this should work.im surprised this happens tho! I can take a look

I'm getting bit by this as well when upgrading. We're using fragments and have multiple tiny presentational components in a single file; for readability, the fragment is defined immediately following the component. Like this:

class ExampleA = ({ someAttr }) => (
  <div className={styles.exampleA}>
    {someAttr}
  </div>
)
export const exampleAQuery = graphql`
  fragment ExampleA on SomeParent {
    someAttr
  }
`

// class ExampleB = …
// export const exampleBQuery = graphql``

So for our case it would be preferable that multiple queries are extracted and executed as they were in v1.0. StaticQuery isn't really an alternatives to fragments in this particular case, though we do intend to use it elsewhere.

Created PR that solves this - https://github.com/gatsbyjs/gatsby/pull/6855.

@jquense I would appreciate You taking a look at it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  Â·  3Comments

dustinhorton picture dustinhorton  Â·  3Comments

andykais picture andykais  Â·  3Comments

signalwerk picture signalwerk  Â·  3Comments

kalinchernev picture kalinchernev  Â·  3Comments