3

I'm using gatsby with contentful data source and gatsby-plugin-react-int.

On each page of my site present the block with latest news, so I use the useStaticQuery hook to get data for the "News" component

export const useStaticNewsQuery = () => useStaticQuery(graphql`
query StaticNews {
  allContentfulNews {
    nodes {
      node_locale
      gatsbyPath(filePath: "/news/{contentfulNews.slug}")
      slug
      title
      body {
        body
      }
      publishDate
    }
  }
}
`)

But as my site is multilingual - I need to get localized news related to the current locale.

As I know - staticQuery does not allow passing variables.

But how can I request in the component only news related to the current locale?

If I'll use pageQuery - I will have to make the same request for each page that includes "News" component in my application and pass the result through the props/context to my "News" component

Maybe I should make some magic in the gatsby-node.js as querying data related to the current locale and pass it through some global context? Also - the same stuff will be with header, footer and other parts of page, that will be rendered by separated components and placed on almost all pages, but should be depended on the current locale

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

1

Given your scenario and your requirements I can only imagine:

  1. Create one staticQuery (useStaticQuery) for each locale to get the news: then you will only need to get the current locale and trigger the needed query like:
    let news;
    if (currentLocale = 'en') news = useStaticNewsQueryEn();
    els if (currentLocale = 'es') news = useStaticNewsQueryEs();
    
  2. As you pointed, use a filtered page query with the value of the current locale of the page
  3. Tweak your gatsby-node.js to get the data there and share it to the needed component (should be always a template or a dynamically created page) and share it via context.

Regarding your shared components (footer, header, etc) you can always render the needed component based on the locale (conditional rendering), that shouldn't be a problem.

You should see what's better performant and more scalable/flexible in your specific use-case.

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • Thank you, Ferran. I doubt that point 1 (static query for each locale) is applicable when the locale set is dynamic Point 2 - i have no problems with getting localized data on the template pages, just do I have to use a query for each page that contains, for example, a footer and then pass the results through props? Point 3 - is it possible to tweak gatsby-node.js when a common (non-page) component is rendered? And/or how can i pass the data to the context? For shared components, data also should be got from the API, and number of locales - also will be depended on api. How to use cond.re – Viktor Limishenko Jul 29 '21 at 06:04
  • 1- It depends on the implementation. Most of the libraries uses a context API to set the locale internally so you can hook your static queries based on that. 2- Yes, that's the idea. If you have more than 3 levels of nesting you may want to use context rather than `props`. 3- No, you can only set a top-level component (pages/templates). For the context, just wrap it inside the `context` object. Your data will be store inside `props.pageContext` (more references at https://www.gatsbyjs.com/docs/creating-and-modifying-pages/) – Ferran Buireu Jul 29 '21 at 06:11
  • 1 As we know - static queries do not allow to use of variables, so how can i pass the context of the locale to the static query? 2 The problem here is that I do not want to request footer data, for each page that uses the footer, I want to do this 1 time for the entire application 3 Then this method does not suit me for transferring data to the footer via the gatsby-node.js So, for now - any variant is not fit to me – Viktor Limishenko Jul 29 '21 at 09:36
  • 1- I'm not saying to use 1 `staticQuery` with the variable (you can't), I'm saying to get the language from the hook and trigger the needed `staticQuery` (1 for each locale) manually set. 2- If the footer changes in each locale, it's not optimal. It's best performant to conditional render the footer needed in each scenario. 3- I think the easy-way implementation is the first one. – Ferran Buireu Jul 29 '21 at 09:49
  • yes, the first point makes sense if I know for sure a list of all available locales, but what if locales are also requested from the API? – Viktor Limishenko Jul 29 '21 at 11:38
  • Then, just create a map or a dictionary to choose which hook trigger. – Ferran Buireu Jul 29 '21 at 11:42
  • That is, create a list of queries for all possible languages in the world? As i know - the list of available languages could be extended in the future And if i'll need to make some changes in to the request, i'll have to make changes to the all identical requests with different languages... – Viktor Limishenko Jul 29 '21 at 11:50
  • Lol... no. Is just a file that retrieves your languages from your API and creates an object like `{'en' : useStaticNewsQueryEn()}`. Then, accessing the position, you'll get the query. There's no way (or at least doesn't comes to my mind) to make it dynamic for an undefined range of languages, it's too much dynamic information for something "static" – Ferran Buireu Jul 29 '21 at 11:53
  • I have to create each request from scratch for example : ``` { 'en' : useStaticNewsQueryEn(graphql`query LatestNewsEn { allContentfulNews (filter: {node_locale: {eq: "en"}})...`) 'de' : useStaticNewsQueryEn(graphql`query LatestNewsDe { allContentfulNews (filter: {node_locale: {eq: "de"}})...` } ``` So, when some changes are required - i should change each of them... – Viktor Limishenko Jul 29 '21 at 11:59
  • Also - it's impossible to create a query string dynamically or using template string, only raw string allowed – Viktor Limishenko Jul 29 '21 at 12:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235414/discussion-between-ferran-buireu-and-viktor-limishenko). – Ferran Buireu Jul 29 '21 at 12:11