Localize the Gatsby Minimal Site Sample

Introduction

This tutorial discusses how to display a localized version of the Gatsby minimal site sample. The goal of this exercise is to modify the application so that it can support multiple languages at the same time and allow users to switch between them easily. The languages are not defined in the application code; rather, they are determined by what is downloaded from the server at build time.

What This Tutorial Includes

This tutorial includes the following:

What This Tutorial Does Not Include

This is what this tutorial does not include:

The Original Gatsby Minimal Site Sample

If you’re unfamiliar with the application discussed in this tutorial, we recommend that you first have a look at the original, English-only version running on the demo site.

You can find the source code for the original application on GitHub.

For an in-depth look at the English-only application and how it was written, have a look at the tutorial.

How the Untranslated Gatsby Minimal Site Sample Works

The existing sample is a simple three-page application. It has a home page, a Contact Us page, and a People page. The first two pages are populated using data pulled by the gatsby-source-oce plugin. This plugin uses REST calls to pull data from the Oracle Content Management server and store it in its cache. The People page uses the gatsby-source-graphql plugin to retrieve the information about the individual people using Oracle Content Management’s native GraphQL support.

Structure of the Untranslated Minimal Site Sample Data

The minimal site sample uses the following Oracle Content Management asset types:

The single-language minimal site sample application consists of the following assets and relationships:

This application code uses predefined slugs as identifiers to reference pages or data sections that need special handling. For example, the home page is identified by the value of its slug (home), even though it is of the same type as the Contact Us (contact-us) page.

How the Untranslated Minimal Site Sample Loads Data from the Oracle Content Management Server

The Gatsby minimal site sample transfers asset data from the server to the Gatsby build cache using two plugins:

Changes Needed to Create a Localized Copy of the Application

Structure of the Localized Asset Data

No changes are needed to the Oracle Content Management asset data types. All the visible translated text can be stored in assets using the existing types.

For the purpose of this exercise, an automated tool was used to create translations of the base data into Canadian French, Spanish (Spain), and Simplified Chinese. This data may have some inaccuracies due to a lack of context in the automated process, but will suffice for this exercise.

As mentioned in the introduction, each translated locale was given its own complete asset tree which can be processed independently of the source language. For example, the English asset tree looks like this:

   MinimalMainGraphQL (slug: minimalmaingraphql)
      Home-Page (slug: home)
            Home-Announcement
            Home-Section1
            Home-Section2
      Contact-Us-Page (slug: contact-us)
            ContactUs-Announcement
            ContactUs-Section1
            ContactUs-Section2
      People-Page (slug: people)
            People-Announcement
            List-of-Person-Assets

and the Spanish one looks like this (note the appended ’_es’ locale in the slugs):

   MinimalMainGraphQL-ES (slug: minimalmaingraphql_es)
      Home-Page-ES (slug: home_es)
            Home-Announcement-ES
            Home-Section1-ES
            Home-Section2-ES
      Contact-Us-Page-ES (slug: contact-us_es)
            ContactUs-Announcement-ES
            ContactUs-Section1-ES
            ContactUs-Section2-ES
      People-Page-ES (slug: people_es)
            People-Announcement-ES
            List-of-Person-Assets-ES

Note how the slugs of the MinimalMain and Page assets share a common root across languages. This is for the following reasons:

Note: Using slugs as special identifiers is not an optimal solution for a localized application and was done in this case to make the asset types and instances as simple as possible. Using different asset types to distinguish pages or adding an untranslatable field would be a more secure approach. Alternatively, taxonomies could be used for the same purpose at the expense of greater code complexity.

Code Modifications Needed to Display a Localized Gatsby Minimal Site Sample

Since all translations are published on the same channel token, no changes are required to the use or configuration of the gatsby-source-oce or gatsby-source-graphql plugins. The only visible change in the application is to add a locale switching control in the page header. (See the description of the Header.jsx file below).

Below are some of the source code changes required to support multiple locales.

gatsby-node.js (original)

Original source code

The file gatsby-node.js performs the following functions:

  1. It loads an asset with a slug named ‘minimalmaingraphql’ using Gatsby’s GraphQL interface. There will be only one asset of type MinimalMain returned. It will also retrieve a list of all images found in the site so it can associate the static URL of each image with any asset that will need to use it.

  2. It collects the data needed to build the common header and footer for each page from the returned MinimalMain instance.

  3. It then extracts the page instances from the same MinimalMain asset and calls page templates to create them. For each page it determines its type by looking at the page slug. A home page will have a slug called ‘home’ and will be created with the pageTemplate.jsx template. A person page will have a slug called ‘people’ and use the peopleTemplate.jsx template. All other pages will be assumed to be generic pages using the pageTemplate.jsx template.

gatsby-node.js (localized)

When working with localized data, gatsby-node.js needs to perform the following extra steps:

  1. It now loads a list of assets that have a name of the form ‘minimalmaingraphql’ rather than looking for a single one. There will be a separate asset for each language, each with the locale appended to the form name, such as minimalmaingraphql_es for Spanish or minimalgraphql_zh for Chinese. The English asset will not have a suffix. Note that the language of each asset is determined by a field inside it, not by the name of the slug. The naming of the slugs is just a convenient way to make them easier to enumerate. Here’s the GraphQL query used to pull all such assets (note the use of the ‘glob’ wildcard to select a pattern):
   minimalMainList: allOceAsset(
      filter: {slug: {glob: "minimalmaingraphql*"}}
    ) {
      nodes {
        id

      description
      oceType
      language
      oceFields {
        pages {
          fields {
            sections {
              name
              id
              type
              typeCategory
            }
          }
          name
          slug
        }
        footerlogo {
          id
          name
          slug
        }
        headerlogo {
          id
          name
          slug
        }
      }
      slug
    }
  }
  1. Looping through the list of these assets, it then builds a list of all the locales present in the data. This will be used to build a control allowing the user to switch locales in the application. By using a query to build this list — as opposed to a static list of locales — the application can be rebuilt if locales are added or removed without requiring any code modification.

  2. The code previously used to build a single set of pages from a single MinimalMain asset is now put in a loop to create a set of pages from each of the MinimalMain assets found in step 1. Previously, the page slug was used as the URL for each page but now the locale of the current MinimalMain asset is inserted into the page URL so that we can have:

    /en/home
    /en/contact-us
    /fr/home
    /fr/contact-us

    instead of

    /home
    /contact-us

    as we did in the single-language version.

src/pages/index.jsx (new)

This file is added to the localized version to allow the site to have a default home page (/). Since all the pages created in the gatsby-node.js file now have a locale prefix to their URL, we need to have a way to give us a default page. The only thing this page does is trigger an immediate load of the ‘/en/home’ page of the site.

src/components/Header.jsx

Original source code

This component must be modified to display a language (locale) switcher control for the application. It gets the required information for this control from the pageTemplate.jsx or peopleTemplate.jsx file that creates it. These two templates in turn received this information from the gatsby-node.js file when it called them to create a page.

src/templates/pageTemplate.jsx and src/templates/peopleTemplate.jsx

Original pageTemplate.jsx
Original peopleTemplate.jsx

These two files need to accept the list of languages from the gatsby-node.js file and pass the list into the Header component for display.

Views of the Localized Sample Site

Here are a few images showing different pages in varying locales. Note that there is text in the header and footer of each page that is untranslated. This is because the text is part of an image, not free text. It would have been possible to create localized versions of the image as well if this was intended to be a production site.

The Spanish home page:

The Spanish home page

The French People page:

The French People page

The Chinese home page:

The Chinese home page