menu

Gatsby

Fast in every way that matters. Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps.

Channels
# All channels
view-forward
# General
view-forward
# I Made This
view-forward
# Meta
view-forward
# Themes
view-forward
Team

Using Variables in a StaticQuery

December 13, 2018 at 10:05pm

Using Variables in a StaticQuery

December 13, 2018 at 10:05pm
Hey Folks - I'm using gatsby-image in my latest project and I'm finding it a bit cumbersome to have to write a whole query just to display an image. I would love to just have a component that I pass a src to and it does it all under the hood.
So - I'm writing a component with StaticQuery that looks like this:
import React from 'react';
import Img from 'gatsby-image';
import { StaticQuery, graphql } from 'gatsby';
function renderImage({ file }) {
return <Img fluid={file.childImageSharp.fluid} />
}
const MyImg = function (props) {
return <StaticQuery
query={graphql`
query {
file(relativePath: { eq: "wes-and-scott.jpg" }) {
childImageSharp {
fluid(maxWidth: 1000) {
...GatsbyImageSharpFluid
}
}
}
}
`}
render={renderImage}
/>
}
export default MyImg;
Now that works amazingly well, BUT I can't make the filename dynamic.
I read in the docs that Static Query can't take variables - only pages. But I don't want my images to be associated with a page - I want to use this component anywhere I want - like a regular img tag.
I tried string interpolation and that doesn't work.
Any way to get around this? Am I thinking about this in the wrong way?
Show previous messages

December 14, 2018 at 5:26pm
Exactly. Also, my main concern was more about overfetching than memory usage. So perhaps you could compare the data usage or loading time on a simulated 3G network between the two approaches.
  • reply
  • like
So you are right. Check out https://dazzling-bohr-1d9d3d.netlify.com/page-4/ which uses the reuseable component. If you look at the js being loaded, you will see the metadata and the base64 for the smallest blurry image being loaded for all 200 images.
  • reply
  • like
Compared to https://dazzling-bohr-1d9d3d.netlify.com/page-3 which uses the one-off component
  • reply
  • like
To give this a number: page-3 (one-time component) is 166KB for all requests
  • reply
  • like
and page-4 (reuseable component) is 219KB transferred total
  • reply
  • like
Which is, to be fair, a 30% increase, even though it's "only" 53KB
Edited
  • reply
  • like
That said, if you're using another source like MDX or MD, then you can use the plugins which will extract just the images being used for those pages.
  • reply
  • like

December 15, 2018 at 1:55am
Yeah, the main question with this technique is how many extra images you're loading metadata for. This can get quite large e.g. https://www.gatsbyjs.org/showcase/ used to load preview images in base64 for every showcase site and a while ago (before I disabled it) it was adding ~250kb extra data which caused a noticeable slowdown in time-to-interactive.
like-fill
1
  • reply
  • like
As long as you're under say ~200 images, you're probably fine
  • reply
  • like
Explored a possible solution to this https://github.com/gatsbyjs/gatsby/issues/10482
like-fill
6
  • reply
  • like

March 13, 2019 at 9:24pm
sorry, but you can't be serious about that! it's impossible to query data by a dynamic id in components? why components then? are you planning to incorporate something like the idea explained in this FR https://github.com/gatsbyjs/gatsby/issues/9843 ?
  • reply
  • like
how should i then realize something like that: i have a page and want to render parts of all wordpress entities linked in the main menu. There i have posts, pages and category archives. can i somehow construct a dynamic query on page level for that? is interpolation possible on page queries?
  • reply
  • like
Hi! You can be sure that Kyle is serious about that and as you can see in the linked issue it’s not an easy to solve problem. But we’re certainly working on it. I don’t fully understand what your question is so it would be cool if you could rephrase that
Edited
like-fill
2
  • reply
  • like
i'm still trying to understand the possibilities i have... if i give a try to the "reusable-component-idea" mentioned above, what is queried or loaded on page render time? in my understanding, the static queries executed on build time, right? then the render part of the static query is executed on page render time, right? so if i query all wordpress pages, posts and category archives and filter them in the render part of the static query, their returned data is delivered to the client and the filtering is done in the client...
  • reply
  • like
what i am trying to achieve is build a simple landing page with gatsby and source-wordpress with a lot sections on the home. every section corresponds to a wordpress menu entry.
  • reply
  • like
the menu entries and hence the sections reflect a wp-page, or a wp-post or all wp-posts of a given category.
  • reply
  • like
so my plan was to build a page, a post and a category section component and let them fetch the data they need.
Edited
  • reply
  • like
so, i guess this is not possible with gatsby, because i need to at least execute 2 queries - 1) for the menu items and 2) for the data needed for the menu items. 2) depends on the results of the first.
  • reply
  • like
ok one more question: am i right, that the only possibility i have so far, is to fetch all wordpress content in one huge query in the indexPage and then filter and split up that data into smaller chunks that i pass into every component in the page, right?
  • reply
  • like

March 14, 2019 at 7:43am
You can do both filtering in the GraphQL queries itself but also on the client-side. Regarding your question: This sounds doable with Gatsby (because you can do two queries, you can use props to pass data) but is certainly off-topic to this discussion. I'd kindly ask you to open a new topic here and ask your question there :) So this thread can be focused on the original topic.
  • reply
  • like

March 15, 2019 at 9:10am
Hello all.
I was trying to solve the same problem yesterday and I ended up with almost the same solution. The main difference is that I use the allImageSharp query instead of doing regex on allFile. Here is my component :
const Image = ({ imgName }) => (
<StaticQuery
query={graphql`
query {
allImageSharp {
edges {
node {
fluid(maxWidth: 500) {
...GatsbyImageSharpFluid
originalName
}
}
}
}
}
`}
render={data => {
const image = data.allImageSharp.edges.find(
edge => edge.node.fluid.originalName === imgName
)
if (!image) {
return null
}
return <Img fluid={image.node.fluid} />
}}
/>
)
export default Image
like-fill
18
  • reply
  • like
I use fragments and I'm ok using StaticQuery every time I want to render a png/jpg/gif/jpeg image
  • reply
  • like
I like this solution best with what gatsby can do at the moment. Going to steal this, thanks!
like-fill
3
  • reply
  • like

September 16, 2019 at 9:21pm
Thank you for the hack [batfkt]
Edited
  • reply
  • like
Show more messages