Gatsby: Passing variables to graphql

Created on 8 Jun 2019  ·  12Comments  ·  Source: gatsbyjs/gatsby

I can pass a variable by using gatsby-node.js as such

        const postsPerPage = 3

        const numPages = Math.ceil(posts.length / postsPerPage)
        Array.from({ length: numPages }).forEach((_, i) => {
          createPage({
            path: i === 0 ? `/blog` : `/blog/${i + 1}`,
            component: path.resolve("./src/pages/blog.js"),
            context: {
              length : posts.length,
              limit: postsPerPage,
              skip: i * postsPerPage,
              currentPage: i + 1,
              numPages
            },

later on in my pages I can receive it as

export const query1 = graphql`
query cockpitHe22($skip: Int!, $limit: Int!) {
  alllo(limit: $limit skip: $skip) {
    edges {
      node {
        Image{
            value{
              publicURL 
              childImageSharp {
                fluid {
                    ...GatsbyImageSharpFluid
                }
            }
          }
        }

now $skip and $limit are accessible.

I wonder if there is any other way to pass a variable to the graphQL query like directly from pages by React instead of dealing with node.

question or discussion

Most helpful comment

Hi @Hypothesis-github!

You can pass arguments inline in GraphQL if you want to pass it at your page level. Variables are mainly meant to be used in "template" pages, for example when you create a page per each node, so the page needs to know which node it's rendering.

Here is how you can pass variables directly:

query cockpitHe22 {
  alllo(limit: 10 skip: 5) {
    edges {
      node {
        Image{
            value{
              publicURL 
              childImageSharp {
                fluid {
                    ...GatsbyImageSharpFluid
                }
            }
          }
        }

This is not what I asked

All 12 comments

Hi @Hypothesis-github!

You can pass arguments inline in GraphQL if you want to pass it at your page level. Variables are mainly meant to be used in "template" pages, for example when you create a page per each node, so the page needs to know which node it's rendering.

Here is how you can pass variables directly:

query cockpitHe22 {
  alllo(limit: 10 skip: 5) {
    edges {
      node {
        Image{
            value{
              publicURL 
              childImageSharp {
                fluid {
                    ...GatsbyImageSharpFluid
                }
            }
          }
        }

Hi @Hypothesis-github!

You can pass arguments inline in GraphQL if you want to pass it at your page level. Variables are mainly meant to be used in "template" pages, for example when you create a page per each node, so the page needs to know which node it's rendering.

Here is how you can pass variables directly:

query cockpitHe22 {
  alllo(limit: 10 skip: 5) {
    edges {
      node {
        Image{
            value{
              publicURL 
              childImageSharp {
                fluid {
                    ...GatsbyImageSharpFluid
                }
            }
          }
        }

This is not what I asked

This is not what I asked

:disappointed:

There is no other way to pass variables, pages are created at gatsby-node level. Your only option is inline variables like I described above, either in page query or in useStaticQuery. We have plans to make useQuery accept variables, but there is no ETA.

I'll be closing this issue as it seems to be related to https://github.com/gatsbyjs/gatsby/issues/10482

Mental, I am stuck. I want the user to be able to select language. I am using prismic and allows to filter for languages using variables in the page query. There is no way to easy way to dynamically set a variables in page queries. I cant set the language dynamically on a page query. This is so unintuitive I am moving over to nextjs.

@skdigital same - don't know how else I can pass locale into Prismic queries at the page level. Ever find a solution?

This is pretty wild. If I have a component that takes an image url as a property ... I can't query for the correct image based on that imageUrl property?

I have the same Problem with my card component as @jfyles. :-/

This is absolutely nuts that you can't pass variables to a query or mutation at the page level. I just ran into this myself today.

@skdigital - I have translations being generated in my wordpress backend (it's easier on the translators), then on build I'm creating nodes for each translation. Then I call them in my graphql like this:

import React from "react"
import { graphql, useStaticQuery } from "gatsby"
import Img from "gatsby-image"
import { useTranslation } from "react-i18next"

const MyComponent = () => {
const data = useStaticQuery(graphql`
    query {
      en: translation(id: { eq: "english-single-pages" }) {
        ...SinglePageTranslations
      }
      es: translation(id: { eq: "spanish-single-pages" }) {
        ...SinglePageTranslations
      }
      de: translation(id: { eq: "german-single-pages" }) {
        ...SinglePageTranslations
      }
      fr: translation(id: { eq: "french-single-pages" }) {
        ...SinglePageTranslations
      }
}
const { i18n } = useTranslation()
  const currentLang = i18n.language.slice(0, 2)
  const t = data[currentLang].translation.specificPage

My solution now is, that i have my pictures for my team grid in a separate folder. And than my query looks like that:

const TeamGrid = ({ teamData }) => (
  <StaticQuery
    query={graphql`
      query MemberImageQuery {
        images: allFile(filter: {relativeDirectory: {eq: "team"}}) {
          edges {
            node {
              base
              childImageSharp {
                fluid(maxWidth: 265) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
    `}
    render={data => (
        <div>
          { teamData.map((member, index) => (
            <Card
              key={index}
              member={member}
              image={
                data.images.edges.find(n => n.node.base === member.image)}
            />
          ))}
        </div>
      )
    }
  />
)

So i just render all my team images without using variables. :) My team data is a json string with all my team members (name, image ). And than i use find() to get the correct edge from the graphQL result. :) Performance is good and have no problems with this solution. :)

Could be another solution the usage of an own source or transformer plugin?🧑‍💻
In this plugins i can do with the data what i want i think. So i can load all my dynamic Data and Images at the same time and after that i just have to iterate over the results.

Did somebody tried that? :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andykais picture andykais  ·  3Comments

magicly picture magicly  ·  3Comments

ferMartz picture ferMartz  ·  3Comments

KyleAMathews picture KyleAMathews  ·  3Comments

hobochild picture hobochild  ·  3Comments