DEV Community

Cover image for Making pageContext available to child components in Gatsby with react-intl
Rhys Malyon
Rhys Malyon

Posted on

Making pageContext available to child components in Gatsby with react-intl

Table of Contents

  1. Background
  2. The Problem
  3. The Solution

1. Background


Check out my portfolio, GitHub, or add me on LinkedIn to get in touch. I'm always looking for new connections or feedback!


I'm currently based out of Japan which means that, when it comes to web development projects, I sometimes have to deal with bilingual websites. When building a static website with HTML, CSS, and JavaScript, it's as easy as creating a new HTML file for each page, copy pasting a basic structure, and pasting in the Japanese copy.

But what happens when you want your website to be more dynamic? What if you want to take advantage of the performance benefits that some frameworks offer? This is a challenge I faced recently when migrating a static website I'd made as a freelance project to Gatsby.

Sure, an argument could be made that going the framework route for static websites might be overkill, but there are a lot of benefits that platforms such as Gatsby have to offer.

If you're into social impact and making a difference, head over to the static website to learn more about Socious. Also Feel free to check out the (work-in-progress) Gatsby website or have a look at the GitHub repo to see how everything fits together.


2. The Problem


If you, like me, are looking for a way to create dynamic, multilingual websites using Gatsby then I'd fully recommend react-intl. Installation is easy, the example code is clear and their explanations are great. There was one problem I faced as a beginner:

Props error

The problem is that part of the functionality react-intl, particularly the SimpleLocalize component, relies on the page's context to derive the current language. This helps determine which text to use and which links to follow but if your page is broken down into separate components like mine then you're likely going to run into this error.


3. The Solution


It might seem fairly obvious but as a relative beginner to Gatsby and React it took me longer than I'd care to admit. After an embarrassing amount of Googling and digging through Stack Overflow I had a moment of clarity: what if the my page's child components didn't know the page context?

I'd just assumed that, because they were being rendered on the page, that they would automatically have access to the information that SimpleLocalize needed, which wasn't the case.

Sure enough, in the end it was as easy as passing down the props of the main page component to the child components and everything came together. I elected to pass all of the page's props using the spread operator ({...props}) but if you're committed to fine-tuning for performance feel free to destructure what you need.

In the end, this is the body of my parent (homepage) component:

const IndexPage = (props) => {
  return (
    <Layout>
      ...
      <AppLinks {...props} />
      ...
    </Layout>
  )
}
Enter fullscreen mode Exit fullscreen mode

And here's how I implemented it in the child component:

const AppLinks = (props) => {
  return (
    <SimpleLocalize {...props}>
      ...
      <FormattedMessage
        id="app-links-header"
      />
      ...
      <FormattedMessage
        id="app-links-subheader"
      />
      ...
    </SimpleLocalize>
  )
}
Enter fullscreen mode Exit fullscreen mode

Sidenote


For each level of nested components you'll need to pass the props along. For example, I had three layers:

- index.js
-- Intro.js
--- EarlyAccessForm.js
Enter fullscreen mode Exit fullscreen mode

Follow the same process at each step and you'll have a working chain of components.

In Intro.js:

<EarlyAccessForm {...props.pageContext} />
Enter fullscreen mode Exit fullscreen mode

And in EarlyAccessForm.js:

...
render() {
  return (
    <SimpleLocalize {...this.props}>
...
Enter fullscreen mode Exit fullscreen mode

I used {...this.props} since EarlyAccessForm is a class-based component but to use it in a functional component just change {...this.props) to {...props}.


And voila, dynamic copy rendered based on the page's current language setting!


English app links


Japanese app links


And there you have it. If you've worked with react-intl before and have any suggestions, feel free to drop them down in the comments!

Discussion (2)

Collapse
jpomykala profile image
Jakub Pomykała

Wow, great content. 🥳 Thanks for mentioning SimpleLocalize!

Collapse
rhysmalyon profile image
Rhys Malyon Author

No worries! Thanks for your work, it made my life a lot easier working with different languages!