Gatsby: load localized content from contentful dynamically

Gatsby is a React-based open source framework with performance, scalability and security built-in. With server-side-rendering, Gatsby is ideal for building a static site with limited user interactions, whose content may not change frequently. Landing pages, blog, news, personal portfolio sites are in this category.

While Gatsby deals with the site generation, Contentful manages the data. More than a headless CMS, Contentful is the API-first content management platform to create, manage and publish content on any digital channel. It's like a database with medias, text and relationship among the data. Gatsby and Contentful can be easily wired to work together, making us easy to maintain a static site.

This article introduces you how to make a Gatsby site with multi-language content managed by Contentful.

Contentful settings

Register a new Contentful account, login and create a new

for your site. Go to your space, navigate to
1Settings -> Locales
page, you will find that Contentful enables two languages by default: English and German. You will need to upgrade your Contentful account if you need more locales. Modify the languages as you like, here I use English and Chinese.

Contentful manages data in a form way.

1Content model
of a table, and
are the table rows. For more information, check the doc here. When creating a
1Content model
, make sure the checkbox `Enable localization of this field` is checked:


Then, you should be able to put content in the

editing view:


Please refer to the Contentful Developers Guide for more details about Contentful locales.

For us, we just need to pass GraphQL parameter

1filter: { node_locale: { eq: $locale } }
to fetch specific languange content from Contentful.


At front-end, we use a Gatsby plugin gatsby-plugin-react-i18next to manage i18n. It seamless integrates with react-i18next. First

1exports.onCreatePage = ({ page, actions }) => {
2  const { createPage, deletePage } = actions
4  if (!page.context.locale) {
5    const language = page.context.i18n.language
6    const locale = language === 'en' ? 'en-US' : language
7    deletePage(page)
9    createPage({
11      context: {
13        locale,
14      },
15    })
16  }
17} @