Gatsby: StaticQuery silently fails when used inside wrapRootElement and wrapPageElement

Created on 30 Aug 2018  Β·  39Comments  Β·  Source: gatsbyjs/gatsby

Description

Using a StaticQuery in a a component inside wrapRootElement or wrapPageElement results in _Loading (StaticQuery)_ both for gatsby-node.js and gatsby-ssr.js.

Steps to reproduce

Using this wrapRootElement implementation the issue appears:

import React from 'react'
import { graphql, StaticQuery } from 'gatsby'

export const wrapRootElement = ({ element }) => (
  <StaticQuery
    query={graphql`
      query {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => element}
  />
)

When using this code, the context is empty which seems to be the reason.

import React from 'react'
import { StaticQueryContext } from 'gatsby'

export const wrapRootElement = ({ element }) => (
  <StaticQueryContext.Consumer>
    {staticQueryData => {
      console.log(staticQueryData)
      return element
    }}
  </StaticQueryContext.Consumer>
)

Expected result

The context should be set for the wrapRootElement and wrapPageElement APIs or if this is intended, there should be a warning in StaticQuery if no context is available.

Actual result

It fails silently and appears to be loading forever.

Environment

  System:
    OS: Linux 4.4 Ubuntu 16.04.5 LTS (Xenial Xerus)
    CPU: x64 Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
    Shell: 4.3.48 - /bin/bash
  Binaries:
    Node: 10.9.0 - ~/opt/node/latest/bin/node
    Yarn: 1.9.4 - ~/opt/node/latest/bin/yarn
    npm: 6.4.1 - ~/opt/node/latest/bin/npm
  Browsers:
    Chrome: 68.0.3440.106
    Firefox: 61.0.1
  npmPackages:
    gatsby: next => 2.0.0-rc.4 
    gatsby-plugin-manifest: next => 2.0.2-rc.1 
    gatsby-plugin-offline: next => 2.0.0-rc.1 
    gatsby-plugin-react-helmet: next => 3.0.0-rc.1 
  npmGlobalPackages:
    gatsby-cli: 1.1.58

File contents (if changed)

gatsby-config.js: N/A
package.json: N/A
gatsby-node.js: see above
gatsby-browser.js: see above
gatsby-ssr.js: N/A

If given some general directions, I would be happy to contribute and make a PR for this issue.

GraphQL bug

Most helpful comment

@antoinerousseau Yep, I'm seeing the same thing. This is a pretty knarly bug I think.

At the moment if you want to initialize your providers with data from a StaticQuery you're kind of stuck. The knock on effect from that is that there's no simple/idiomatic way to share a single piece of static data globally across the application afaics.

All 39 comments

So StaticQueryContext is used only in development, so using that directly in production won't work anywhere in component tree. Are you sure it doesn't work for wrapPageElement? I can definitely see it won't work for wrapRootElement

The StaticQueryContext part was just a test to figure out the problem, I don't intend on using it in my code.
Yes, I'm sure it doesn't work for both wrapRootElement and wrapPageElement. I just tried it again with the default starter and the development mode shows the loading message and the production build crashes with this error:

error Generating JavaScript bundles failed


  Error: ./gatsby-browser.js
  Module not found: Error: Can't resolve 'public/static/d/3892401927.json' in '/home/buger  t/repos/gatsby-site'
  resolve 'public/static/d/3892401927.json' in '/home/bugert/repos/gatsby-site'
    Parsed request is a module
    using description file: /home/bugert/repos/gatsby-site/package.json (relative path: .)      Field 'browser' doesn't contain a valid alias configuration
      resolve as module
        looking for modules in /home/bugert/repos/gatsby-site/node_modules
          using description file: /home/bugert/repos/gatsby-site/package.json (relative pa  th: ./node_modules)
            Field 'browser' doesn't contain a valid alias configuration
            using description file: /home/bugert/repos/gatsby-site/package.json (relative   path: ./node_modules/public/static/d/3892401927.json)
              no extension
                Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n doesn't exist
              .js
                Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n.js doesn't exist
              .jsx
                Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n.jsx doesn't exist
              as directory
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n doesn't exist
        /home/bugert/repos/node_modules doesn't exist or is not a directory
        /home/bugert/node_modules doesn't exist or is not a directory
        /home/node_modules doesn't exist or is not a directory
        /node_modules doesn't exist or is not a directory
        looking for modules in /home/bugert/repos/gatsby-site/
          using description file: /home/bugert/repos/gatsby-site/package.json (relative pa  th: .)
            Field 'browser' doesn't contain a valid alias configuration
        looking for modules in /
          No description file found
          Field 'browser' doesn't contain a valid alias configuration
        looking for modules in /home/bugert/repos/gatsby-site/node_modules
          using description file: /home/bugert/repos/gatsby-site/package.json (relative pa  th: ./node_modules)
            Field 'browser' doesn't contain a valid alias configuration
        looking for modules in /home/
          No description file found
          Field 'browser' doesn't contain a valid alias configuration
        looking for modules in /home/bugert/
          No description file found
          Field 'browser' doesn't contain a valid alias configuration
        looking for modules in /home/bugert/repos/
          No description file found
          Field 'browser' doesn't contain a valid alias configuration
            using description file: /home/bugert/repos/gatsby-site/package.json (relative   path: ./public/static/d/3892401927.json)
              no extension
                Field 'browser' doesn't contain a valid alias configuration
          No description file found
          no extension
            Field 'browser' doesn't contain a valid alias configuration
            using description file: /home/bugert/repos/gatsby-site/package.json (relative   path: ./node_modules/public/static/d/3892401927.json)
              no extension
                Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/public/static/d/3892401927.json doesn't exi  st
              .js
                Field 'browser' doesn't contain a valid alias configuration
            /public/static/d/3892401927.json doesn't exist
          .js
            Field 'browser' doesn't contain a valid alias configuration
          No description file found
          no extension
            Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n doesn't exist
              .js
                Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/public/static/d/3892401927.json.js doesn't   exist
              .jsx
                Field 'browser' doesn't contain a valid alias configuration
            /public/static/d/3892401927.json.js doesn't exist
          .jsx
            Field 'browser' doesn't contain a valid alias configuration
          No description file found
          no extension
            Field 'browser' doesn't contain a valid alias configuration
            /home/public/static/d/3892401927.json doesn't exist
          .js
            Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n.js doesn't exist
              .jsx
                Field 'browser' doesn't contain a valid alias configuration
                /home/bugert/repos/gatsby-site/public/static/d/3892401927.json.jsx doesn't   exist
            /public/static/d/3892401927.json.jsx doesn't exist
              as directory
                /home/bugert/repos/gatsby-site/public/static/d/3892401927.json doesn't exi  st
          No description file found
          no extension
            Field 'browser' doesn't contain a valid alias configuration
            /home/bugert/public/static/d/3892401927.json doesn't exist
          .js
            Field 'browser' doesn't contain a valid alias configuration
            /home/public/static/d/3892401927.json.js doesn't exist
          .jsx
            Field 'browser' doesn't contain a valid alias configuration
          as directory
            /public/static/d/3892401927.json doesn't exist
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n.jsx doesn't exist
              as directory
                /home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.jso  n doesn't exist
            /home/bugert/repos/public/static/d/3892401927.json doesn't exist
          .js
            Field 'browser' doesn't contain a valid alias configuration
            /home/bugert/public/static/d/3892401927.json.js doesn't exist
          .jsx
            Field 'browser' doesn't contain a valid alias configuration
            /home/public/static/d/3892401927.json.jsx doesn't exist
          as directory
            /home/public/static/d/3892401927.json doesn't exist
            /home/bugert/repos/public/static/d/3892401927.json.js doesn't exist
          .jsx
            Field 'browser' doesn't contain a valid alias configuration
            /home/bugert/public/static/d/3892401927.json.jsx doesn't exist
          as directory
            /home/bugert/public/static/d/3892401927.json doesn't exist
            /home/bugert/repos/public/static/d/3892401927.json.jsx doesn't exist
          as directory
            /home/bugert/repos/public/static/d/3892401927.json doesn't exist
  [/home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.json]
  [/home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.json.js]
  [/home/bugert/repos/gatsby-site/node_modules/public/static/d/3892401927.json.jsx]
  [/home/bugert/repos/node_modules]
  [/home/bugert/node_modules]
  [/home/node_modules]
  [/node_modules]
  [/package.json]
  [/home/package.json]
  [/home/bugert/package.json]
  [/home/bugert/repos/package.json]
  [/public/static/d/3892401927.json/package.json]
  [/home/bugert/repos/gatsby-site/public/static/d/3892401927.json]
  [/public/static/d/3892401927.json]
  [/home/public/static/d/3892401927.json/package.json]
  [/home/bugert/repos/gatsby-site/public/static/d/3892401927.json.js]
  [/public/static/d/3892401927.json.js]
  [/home/bugert/public/static/d/3892401927.json/package.json]
  [/home/public/static/d/3892401927.json]
  [/home/bugert/repos/gatsby-site/public/static/d/3892401927.json.jsx]
  [/public/static/d/3892401927.json.jsx]
  [/home/bugert/repos/public/static/d/3892401927.json/package.json]
  [/home/bugert/public/static/d/3892401927.json]
  [/home/public/static/d/3892401927.json.js]
  [/home/bugert/repos/public/static/d/3892401927.json]
  [/home/bugert/public/static/d/3892401927.json.js]
  [/home/public/static/d/3892401927.json.jsx]
  [/home/bugert/repos/public/static/d/3892401927.json.js]
  [/home/bugert/public/static/d/3892401927.json.jsx]
  [/home/bugert/repos/public/static/d/3892401927.json.jsx]
   @ ./gatsby-browser.js 1:0-62 12:10-25
   @ ./.cache/api-runner-browser-plugins.js
   @ ./.cache/api-runner-browser.js
   @ ./.cache/production-app.js

I ve got the same problem after many research it's appear that you need to put the file where is located your staticquery in the folder ./src else you will get "Loading (StaticQuery)"

so what i did:
in gatsby-ssr and gatsby-browser

var provider = require(`./src/inject-provider`)  
exports.wrapPageElement = provider.wrapPageElement

and in inject-provider.js (that you can use esmodule so import and so on) your layout with the static-query.

Certainly because babel compile only in src/*.js

WILL BE GREAT to add this in the DOC
Thanks gatby

I'm making a Gatsby plugin and I have to expose part of my plugin config to the browser. I'm exposing part of the config to GraphQL and using StaticQuery inside wrapRootElement, but that does not work. How do I (and other plugin creators) accomplish this?

I ve got the same problem after many research it's appear that you need to put the file where is located your staticquery in the folder ./src else you will get "Loading (StaticQuery)"

I seem to have run into this issue also. But my code is already inside the src. I use other StaticQueries without problem. Just one that is building a cache and used in wrapRootElement causes problems.

It seems to work when doing the build. Its just in development that fails with the Loading text

Also butting up against this issue while trying to expose some data from the Gatsby data through to the client for some initial state.

Neither wrapRootElement nor wrapPageElement work with <StaticQuery>

I'm also encountering this issue.

Can confirm that wrapRootElement works fine with in build, but not in dev.

I'm looking for a way to use StaticQuery in an npm package. Does anyone know if it's possible?

@krabbypattified and @TylerBarnes - I have been looking through the Gatsby source for a way to do this. I have a _workaround_ πŸ˜„ (i.e. hacky abuse of the .cache) that seems to be working for me in development.

I copy any components with queries from my local plugin directory to .cache/fragments/ during onPreExtractQueries. Gatsby picks these files up during query extraction which means your query fragments are ready to use. (We use this to dynamically create a fragment based on site metadata as well.)

@elskwid thanks for the tip, I'm gonna give that a shot!

Fyi, I was able to get my <StaticQuery> working with wrapPageElement but not wrapRootElement.
I'm using it to load i18n messages into react-intl's <IntlProvider> in the root layout.
But it might means that <IntlProvider> is re-mounting on each page change...

@antoinerousseau Yep, I'm seeing the same thing. This is a pretty knarly bug I think.

At the moment if you want to initialize your providers with data from a StaticQuery you're kind of stuck. The knock on effect from that is that there's no simple/idiomatic way to share a single piece of static data globally across the application afaics.

I copy any components with queries from my local plugin directory to .cache/fragments/ during onPreExtractQueries. Gatsby picks these files up during query extraction which means your query fragments are ready to use. (We use this to dynamically create a fragment based on site metadata as well.)

@elskwid Could you share that code? We started a new project and are again having this issue.

@antoinerousseau and @jedrichards (and the rest of you :wave:). We were able to get a component to stay mounted across page changes by using wrapPageElement.

I created a SiteContext component so I could share the providers between browser and ssr and have a central place to make additions/changes. In this case, we have a client-side search provider:

import { ChildrenType } from '../../types'
import { SearchProvider } from '../Search'
import React, { Fragment } from 'react'

/**
 * Component used to wrap the `PageElement`.
 *
 * Provides a way to connect state that can persist through page transitions.
 *
 * @param {Props} props
 */
const propTypes = {
  ...ChildrenType.isRequired,
}

const SiteContext = ({ children }) => (
  <Fragment>
    <SearchProvider>
      {children}
    </SearchProvider>
  </Fragment>
)

SiteContext.propTypes = propTypes

export default SiteContext

Then in gatsby-browser.js and gatsby-ssr.js:

import React from 'react'
import SiteContext from '../src/components/SiteContext'

const wrapPageElement = ({ element, props }) => {
  return <SiteContext {...props}>{element}</SiteContext>
}

export default wrapPageElement

You can test out the mounting/unmounting by changing SiteContext to do a little logging...

import { ChildrenType } from '../../types'
import { SearchProvider } from '../Search'
import React, { Fragment, PureComponent } from 'react'

/**
 * Component used to wrap the `PageElement`.
 *
 * Provides a way to connect state that can persist through page transitions.
 *
 * @param {Props} props
 */

const propTypes = {
  ...ChildrenType.isRequired,
}

class SiteContext extends PureComponent {

  componentDidMount() {
    console.log('>>> SiteContext did mount')
  }

  componentWillUnmount() {
    console.log('>>> SiteContext will unmount')
  }

  render() {
    const { children } = this.props

    return (
      <Fragment>
        <SearchProvider>
          {children}
        </SearchProvider>
      </Fragment>
    )
  }
}

SiteContext.propTypes = propTypes

export default SiteContext

We see SiteContext mount once and stay mounted through the page transitions.

I hope that helps.

@coxom this code is buried in a pretty complicated internal plugin at the moment. _I should note that this process is only needed if you have a plugin or external library that needs to add fragments to the site._ If you're looking for a way to get general usage fragments in a more standard setup just let me know, we have a way we're doing that too. πŸ˜‰

Essentially, we have a file with GraphQL fragments in it (i.e. site-metdata-fragments.js):

import { graphql } from 'gatsby'

export const siteMetadataFields = graphql`
  fragment SiteMetadataFields on Site {
    siteMetadata {
    }
  }
`

Then, in gatsby-node.js we copy this file into the .cache folder using the onPreExtractQueries hook. Ours is more complicated but it's basically a simple file copy from site-metadata-fragments.js go .cache/fragments/site-metadata-fragments.js.

By using this hook, the fragments are present when Gatsby extracts the queries, so you can use them in your app.

Does that give you enough to go on?

@elskwid I tried the strategy to copy the fragments into the .cache and I'm still getting the "Loading (StaticQuery)". Using gatsby 2.0.19

My use-case is similar to @krabbypattified. I'm loading translations and currencies.

Ok there are few things that need to be solved:

Hiya!

This issue has gone quiet. Spooky quiet. πŸ‘»

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

Thanks for being a part of the Gatsby community! πŸ’ͺπŸ’œ

The project that I need this for just got active again. Any news on a fix?

@coxom Workaround from @elskwid should work - important bits from it:

  • StaticQuery need to be used in component inside src directory (because Gatsby doesn't extract queries if it's not)
  • use wrapPageElement for now

@pieh I am using that workaround but for a production release it would be useful to have the code only load once and not on every page change.

@coxom fwiw I'm using wrapPageElement and storing initialisation state to localStorage so that it only reloads on a new build, not on every page load or refresh. Not ideal but in my case I'm initialising a lot of data so it's significantly improved performance until there's a proper resolution to this issue.

Possibly related / helpful to someone:
We're importing a component using <StaticQuery> from gatsby-ssr.js. It fails silently on dev, but it's fine on build.

Interestingly, switching from <StaticQuery> to the useStaticQuery() hook fails loudly on dev - but again is fine on build.

Another workaround. I'm currently running all queries inside createPages and then saving all data I need available within providers as json files within static/global. Then in the providers I just import the data I need from that static directory.

I initially had issue implementing the work around of using useStaticQuery inside of wrapPageElement, However had an issue where gastbsy could not open the generated query file.

Moving useStaticQuery to inside a component inside /src/components then importing that component into wrapPageElement and it worked.

Any updates on this? I’m running into a similar issue. Wrapping at the page level requires my component refetch the data on each page change. I’m trying to fetch translation strings from JSON to initialize i18next

Top-level wrappers are pretty much a standard in the React ecosystem. I'm surprised this issue has only so little traction.

We need a reasonable way to handle this as well. Passing providers on component level seems suboptimal at best.

+1

Hi all. I have that issue only in iframe.
So it works in prod, but doesn't work in develop. And works without iframe.
I have added in gatsby-ssr

exports.wrapPageElement = ({element}) => {
  useMenuData()
  return element
}

where useMenuData has useStaticQuery
Is it possible to useStaticQuery in iframe in develop?

Getting the same problem when using the material-ui template from https://github.com/mui-org/material-ui/blob/master/examples/gatsby/plugins/gatsby-plugin-top-layout/TopLayout.js

<Helmet> is in <TopLayout> which is in a custom plugin defined by the template. As soon as I added useStaticQuery there, I got:

gatsby-browser-entry.js:76 Uncaught Error: The result of this StaticQuery could not be fetched.

This is likely a bug in Gatsby and if refreshing the page does not fix it, please open an issue in https://github.com/gatsbyjs/gatsby/issues
    at useStaticQuery (gatsby-browser-entry.js:76)
    at TopLayout (TopLayout.js:13)
    at renderWithHooks (react-dom.development.js:14826)
    at mountIndeterminateComponent (react-dom.development.js:17506)
    at beginWork (react-dom.development.js:18630)
    at HTMLUnknownElement.callCallback (react-dom.development.js:189)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:238)
    at invokeGuardedCallback (react-dom.development.js:293)
    at beginWork$1 (react-dom.development.js:23235)
    at performUnitOfWork (react-dom.development.js:22186)
    at workLoopSync (react-dom.development.js:22162)
    at performSyncWorkOnRoot (react-dom.development.js:21788)
    at scheduleUpdateOnFiber (react-dom.development.js:21220)
    at updateContainer (react-dom.development.js:24408)
    at react-dom.development.js:24793
    at unbatchedUpdates (react-dom.development.js:21935)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:24792)
    at render (react-dom.development.js:24875)
    at app.js:67

Not sure I understand how to work around this from the above, other than moving <Helmet>

EDIT: Interestingly, duplicating the query inside another component in the src tree, fixes this.

+1
I have exactly the problem like @georgiosd mentioned above.
Any news on this? :(

I am going thru the same issue right now; see details at: https://stackoverflow.com/questions/63037661/loading-staticquery-white-screen-on-gatsby

This was fixed in https://github.com/gatsbyjs/gatsby/pull/25723

Static queries should now _just work_ in wrapRootElement or wrapPageElement

Upgrade to [email protected] and try it out! πŸ™‚

Is this problem really solved? I keep getting the following error:

Generating SSR bundle failed

Can't resolve 'public/static/d/3159585216.json' in '/Users/a1/private/za-Szklem'

If you're trying to use a package make sure that 'public/static/d/3159585216.json' is installed. If you're trying to use a local file make sure that the path is correct.

File: gatsby-ssr.js

not finished Building static HTML for pages - 2.181s

I updated to the given version, and I do something like this (in gatsby-ssr.js):

import React from 'react';
import { graphql, StaticQuery } from 'gatsby';
import { wrapRootElement as wrap } from './root-wrapper';

export const wrapRootElement = wrap;

export const wrapPageElement = ({ element, props }) => {
  return (
    <StaticQuery
      query={graphql`
        query {
          site {
            siteMetadata {
              title
            }
          }
        }
      `}
      render={data => <h1>test {element}</h1>}
    />
  );
};

Getting the exact same issue. Can't seem to use static queries in any way whatsoever. The site fails with a Can't resolve error looking for the json file of a static query.

I got the same error when try use StaticQuery in gatsby-ssr.js (wrapRootElement).

My error:

success Building production JavaScript and CSS bundles - 4.956s
success Rewriting compilation hashes - 0.004s
error Generating SSR bundle failed

Can't resolve 'public/page-data/sq/d/63159454.json' in '/Users/myname/GitHub/devchallenges/windbnb'

If you're trying to use a package make sure that 'public/page-data/sq/d/63159454.json' is installed. If you're trying to use a local file make sure that the path is correct.

Check in public/page-data/sq/d/63159454.json

{"data":{"site":{"siteMetadata":{"title":"Gatsby Default Starter","description":"Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.","author":"@gatsbyjs"}}}}

Anyone knows how's going about this? πŸ‘€

I'm also seeing the same webpack error as @tranlehaiquan

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dustinhorton picture dustinhorton  Β·  3Comments

jimfilippou picture jimfilippou  Β·  3Comments

hobochild picture hobochild  Β·  3Comments

kalinchernev picture kalinchernev  Β·  3Comments

ferMartz picture ferMartz  Β·  3Comments