I'd like to start by saying that Gatsby is amazing! I'm closing up a project and made the decision to migrate a React site to Gatsby in order to get SEO/social meta working properly. I was able to migrate the whole project in less than 24 hours with very basic Gatsby experience and I feel like it would have been even faster had I not gone through several inconsistencies between the dev and build experiences. These are things that I would have also stumbled through if I had started the project from scratch.
flash of unstyled content during dev / does not happen after build:
I spent some time trying to figure out why this was happening and remember being extremely frustrated when I found out it doesn't happen after building the project...
references to the global window causing the build to crash:
I wish there were an option to specify what type of build you are doing (not ssr) so that we aren't forced to have to check for the presence of global objects like window when having to use it outside of componentDidMount
some kind of way of creating reusable gatsby-image components:
Not an inconsistency but a wonderful nice to have... I spent quite some time trying to figure out how to make a reusable Gatsby-Image component that could be fed image hrefs that are sourced from a json file... there was no intuitive way to get this to work, so no benefits of Gatsby-Image in this project
I feel like what you see during dev is exactly what we should see after we build but having said that, I deeply appreciate your efforts and will definitely use it again, thanks 鉁岋笍
馃憢 Hi @eballeste! I don't think I can accurately answer question 1, but I have some comments for the other two!
window in my application is by checking if window is undefined: {typeof window !== 'undefined' && window.innerWidth >= 760 ? <Nav /> : ''} though I'm not 100% certain this is the best approach, it certainly works.Thanks @josefaidt I'm not looking for workarounds, the workarounds have already been implemented in my project... my whole motivation for this post is as inspiration for possible direct solutions to these problems...
mostly, the output of develop should be the same output with build... right now that's not the case
@eballeste What are you using to style your content?
I was using styled components when I was learning Gatsby... didn't use the official plugin... just a direct npm install of the package and I suffered from the initial flash of un-styled content.
Once I installed the styled components plugin from Gatsby plugins... everything worked well.
Not sure if that helps. But thought I'd mention it.
First of all--thanks for the feedback. We appreciate it!
Let me address a few of your points:
1 and 2 are both related to unifying development and build behavior, which is very much something we're aware of--and we've seen a number of issues related to what you describe. In general, this is a challenging problem to solve. We need to balance developer experience (e.g. don't want to introduce slow development cycles and waiting for things to compile) with a version of the application that is as production-like as possible. We're not there yet--but we're working on it, and will continue to improve!
3 you can do, but perhaps you aren't able to do it as cleanly as you'd like. Specifically, if we can do #10482 cleanly at some point in the future, I think that would really help create a reusable component.
For now, a sort-of hacky solution (but which works just fine, and doesn't really have a perf. hit) is to query _all_ the images your JSON files could access, and then display just that image with that component.
Given a folder structure like:
images/
a.json
b.json
and a.json and b.json both pull images from images, e.g. a.json
{
"image": "images/a.jpg"
}
We could create a re-usable image component like so:
import React from 'react'
import { useStaticQuery, graphql } from 'gatsby'
import Image from 'gatsby-image'
function ReusableImage({ path }) {
const { data } = useStaticQuery(graphql`
{
images: allFile(
filter:{
relativePath:{
glob:"images/**/*"
}
}
) {
edges {
node {
relativePath
childImageSharp {
fluid(maxWidth:500) {
...GatsbyImageSharpFixed
}
}
}
}
}
}
`)
const images = data.images.edges.reduce((lookup, { node: image }) => {
lookup[image.relativePath] = image.childImageSharp.fluid
return lookup
}, {})
const image = images[path]
if (!image) {
// TODO: handle error case
return null
}
return <Image fluid={image} />
}
export default ReusableImage
Now we can use this reusable image with something like <ReusableImage path="images/a.jpg" /> and that should work like you'd expect.
Not a perfect solution--but it does accommodate the use case you specify.
We'd be happy to answer any feedback you may have, but as this isn't something we can immediately remediate or provide a structured fix/solution, I'm going to close this as answered.
Please feel free to continue the discussion if you feel that there's something we can act upon with this feedback, or happy to take any of these items as separate issues if they don't already exist!
Most helpful comment
First of all--thanks for the feedback. We appreciate it!
Let me address a few of your points:
1 and 2 are both related to unifying development and build behavior, which is very much something we're aware of--and we've seen a number of issues related to what you describe. In general, this is a challenging problem to solve. We need to balance developer experience (e.g. don't want to introduce slow development cycles and waiting for things to compile) with a version of the application that is as production-like as possible. We're not there yet--but we're working on it, and will continue to improve!
3 you can do, but perhaps you aren't able to do it as cleanly as you'd like. Specifically, if we can do #10482 cleanly at some point in the future, I think that would really help create a reusable component.
For now, a sort-of hacky solution (but which works just fine, and doesn't really have a perf. hit) is to query _all_ the images your JSON files could access, and then display just that image with that component.
Given a folder structure like:
and a.json and b.json both pull images from images, e.g. a.json
We could create a re-usable image component like so:
Now we can use this reusable image with something like
<ReusableImage path="images/a.jpg" />and that should work like you'd expect.Not a perfect solution--but it does accommodate the use case you specify.
We'd be happy to answer any feedback you may have, but as this isn't something we can immediately remediate or provide a structured fix/solution, I'm going to close this as answered.
Please feel free to continue the discussion if you feel that there's something we can act upon with this feedback, or happy to take any of these items as separate issues if they don't already exist!