gatsby: StaticQuery silently fails when used inside wrapRootElement and wrapPageElement
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.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 23
- Comments: 46 (10 by maintainers)
Commits related to this issue
- First try Not building "Generating development SSR bundle failed" error see: https://github.com/gatsbyjs/gatsby/issues/7747 — committed to decimoseptimo/rickandmortyapi by decimoseptimo 3 years ago
Is this problem really solved? I keep getting the following error:
I updated to the given version, and I do something like this (in gatsby-ssr.js):
@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.
Ok there are few things that need to be solved:
wrapRootElement(but abovewrapPageElement) I think we need to splitjson-storeinto separate components - one for page query results and one for static query results - both will need to listen to socketIO messages - just one will handle static queries and one will handle page queries. New component with page query results could wrap exported element here https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/root.js#L119.gatsby-browser.js- right now we scan only files insrcdirectory - https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/internal-plugins/query-runner/query-compiler.js#L102-L105. This is pretty expensive so we can’t scan all files in root of the project - especially we can’t scan all ofnode_modules.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
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
This was fixed in https://github.com/gatsbyjs/gatsby/pull/25723
Static queries should now just work in
wrapRootElementorwrapPageElementUpgrade to
gatsby@2.24.13and try it out! 🙂The project that I need this for just got active again. Any news on a fix?
Fyi, I was able to get my
<StaticQuery>working withwrapPageElementbut notwrapRootElement. I’m using it to load i18n messages intoreact-intl’s<IntlProvider>in the root layout. But it might means that<IntlProvider>is re-mounting on each page change…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
where useMenuData has
useStaticQueryIs it possible to useStaticQuery in iframe in develop?@elskwid Could you share that code? We started a new project and are again having this issue.
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.
Another workaround. I’m currently running all queries inside
createPagesand then saving all data I need available within providers as json files withinstatic/global. Then in the providers I just import the data I need from that static directory.Possibly related / helpful to someone: We’re importing a component using
<StaticQuery>fromgatsby-ssr.js. It fails silently on dev, but it’s fine on build.Interestingly, switching from
<StaticQuery>to theuseStaticQuery()hook fails loudly on dev - but again is fine on build.@coxom fwiw I’m using
wrapPageElementand 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.@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 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):
Then, in
gatsby-node.jswe copy this file into the.cachefolder using theonPreExtractQuerieshook. Ours is more complicated but it’s basically a simple file copy fromsite-metadata-fragments.jsgo.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?
@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/duringonPreExtractQueries. 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.)