Skip to main content

Travis Stanley

Techlead for the Webteam @ Fitplan. Adoring partner, father of three, Codemonkey, gamer, and writer. Thats about the gist of it.

2 min read · March 1st 2019

A method for Localization with Gatsby and Sanity.io

Localization is a common problem and there are many solutions, each with their own benefits and trade-offs. With Gatsby and Sanity.io its possible to achieve a solution that is easy to work with and extend. If you haven’t already read about why Gatsby and Sanity.io pair so well check out the blog post by Knut Melvær: Blazing fast development with Gatsby and Sanity.io.

I have completed two sites with Gatsby and Sanity that required localization. The first site needed to maintain every link from the original site without redirects: each language living in its own subdomain, es.my-web-page.com for example. The simplest solution at the time was to use multiple builds which always bothered me. The second site I vowed to do it the right™ way.

The new setup would generate pages for every language in one build step giving urls like my-home-page.com/es/.... This makes it easier for both the content team and our developers to use.

Setting Up Sanity to Support Translations

Sanity.io has some good documentation which has great examples to help you achieve localized text.

Create a new contentType schema called localeText to use with the schemas in your project.

This will allow you to add localeText as a type in your schemas and renders a nice UI for adding translations. Example of the translation UI from Sanity

In your schema:

Updating Gatsby Setup

Now that you have your Sanity schemas set up for adding translations you need to set up your Gatsby project to handle them. You’re going to update the queries to handle the new shape of your data.

Which gives you a data prop that looks like the following:

Getting the Correct Language Text

At this point you could use the above as-is in your components with data.sanitySomeDataType.title.en. You could do something like:

It is preferable to reference only the title key and get the correct text. No need to remember what locale is active.

So let’s make that work.

Once again, you can use the example from the Sanity.io documentation for a function to localize the text from a given Sanity document. I’ve modified the example below to always default to English. This suits my use case and it’s a good starting point if your use case differs. The function walks through a given document and updates any object with _type: 'locale<TEXT_TYPE>' ( for example _type: 'localeText', or _type: 'localeString' ) and returns only the correct translation text.

You could use render props for this but I decided on a higher-order component (HOC).

Wrap Page Components With the Localize HOC

For each page or template that needs to be localized add your HOC.

Generating Pages with the Correct Context

In the gatsby-node.js file you need to add a function that generates pages for each supported language with a path prefix for each, such as ‘es’ for Spanish, and ‘fr’ for French. It needs to be called in onCreatePage so that every automatically generated page from your pages directory gets localized. It also needs to be added into the createPages to localize all of your dynamic content. This is needed as gatsby doesn’t call onCreatePage for pages generated by the same plugin at the moment to avoid infinite loops.

Sanity.io + Gatsby.js + Localization = Win

If you haven’t already started using Sanity.io as your content backend I encourage you to check it out. You and your content team will love it.

For a quick start with the combo, the peeps at Sanity put up a great starting point at Combo Example: Company Website

If you have any questions or want to geek out about all things React hit me up on Twitter @cpt_silverfox

Tagged with sanity, i18nView all Tags

Enjoyed this post? Receive the next one in your inbox!

Docs
Tutorials
Plugins
Blog
Showcase