Multi-Language Frontend - Building Pages & Cards | Yext Hitchhikers Platform

What You’ll Learn

In this section, you will learn:

  • How to add pages for additional languages
  • How fallback works using shallow merging
  • Best practices for how to manage your pages and cards

Overview

If you haven’t already, make sure to read or refresh yourself on how Pages & Cards work in the Search frontend in the Core Frontend - Adding Pages & Cards Module . In that module, we review how you can use Jambo Commands to add Pages for each vertical in your experience and how to fork cards from the Theme if you want to modify or customize a card for your use.

Well, good news - things work the same way when you’re building a multi-language site!

Just like in a single-language experience, you’ll need to:

  • Create a page for universal search for each language
  • Create a page for each vertical for each language
  • Update things like verticalKey and cardType in the config.json file
  • Modify any scss in the answers-variables.scss or answers.scss files

Creating Pages

When you create a new page in a single-language experience, you just need to include the “[pageName]“, e.g., “locations”, which generates the 2 files needed for each page:

  • pages/locations.html.hbs
  • config/locations.json

default language add page

This is how you want to name pages for your default language. For any additional languages, you’ll need to include the locale code so that it’s “[pageName].[localeCode]“, e.g., “locations.fr”, which will generate the 2 files needed like this:

  • pages/locations.fr.html.hbs
  • config/locations.fr.json

additional language add page notation

The localeCode specified here must match the locale_config.json locale code / the profile locale code in Content. The [pageName].[localeCode] notation is incredibly important and tells Jambo when it’s building your output pages which pages are associated to which locale, what the url paths should be, and which pages share the same pageName parent for fallback behavior (which we’ll talk about next). It’s very important to get this right and you will likely see errors in your console or builds so you should double check the notation as a first step when debugging.

Here’s what your file directory might look like if you have Universal Search, Locations and FAQs for English (default), German, Italian, Spanish and French.

file directory with all languages specified

Fallback Behavior

Fallback behavior is a feature that can help you save time when building out pages for additional languages. You can use the fallback behavior to reduce the amount of duplicative work you have to do by letting you “fallback” to the default language (or another language if specified in locale_config.json). We will always fallback to the default language, but you can optionally specify in the locale_config.json if you want a language to fallback to another language first.

Note that if you are creating a Search experience using a language other than the 6 main supported languages (see the supported languages reference doc to learn more), you will need to set a fallback language to one of the supported languages. This helps avoid errors when building your site.

Here’s how fallback behavior works:

For the config.json files

For any pages that share the same [pageName], we will do a shallow merge of the configuration files.

A shallow merge means that the merge only goes one level deep, which means the additional language pages can inherit any of the top-level properties like verticalsToConfig or componentSettings in the config.json file - but it’s all or nothing. If, for example, you want to have different settings for the Facets object on your English and French page, you’ll need to specify your full componentSettings object in the fr.json file, including components other than Facets. If all files have all top-level properties defined, no merging will occur.

For example, you could just have a config.json file like this for an additional language:

{
  "verticalKey": "locations", 
  "pageTitle": "Établissements Chercher" 
  // "metaDescription": "", 
  // "canonicalUrl": "", 
  // "keywords": "", 
}

This means that the componentSettings and verticalsToConfig objects will “fallback” on the default language’s componentSettings and verticalsToConfig objects. Note: You must include the verticalKey in all config.json files at a minimum. All other top-level properties are optional and if not included will shallow merge with the default / fallback locale(s).

For the html.hbs files

Additionally, if you don’t have an html.hbs file for a non-default language, Jambo will use the default language’s html.hbs file for the layout. In many cases, you will probably be able to delete the html.hbs file for your additional languages whenever you want the verticals to look the exact same across languages.

For example, this would be a valid file directory for the site referenced above with Universal Search, Locations and FAQs in English (default), German, Italian, Spanish and French. Here, you are using the same layout for all languages for the FAQs vertical, you are overriding the Universal Search template in Spanish and Italian (e.g., maybe you don’t want to include the Q&A component in those languages), and you are overriding the Locations layout in German (e.g., maybe you don’t want to include facets).

file directory using fallback for layout

Keep in mind that all verticals must have a config.json file, but not all verticals need the layout/html.hbs file. If you don’t have the config.json file, the vertical will not exist in that language.

Fallback Examples

Now this is a pretty complex topic so let’s take a look at some examples using a brand that has Products, Locations and FAQs and a site that has English (default), French and German.

Example 1 - Site with 3 Languages that are completely consistent across languages

In this example, let’s assume you want all 3 verticals in all languages and you want them to be exactly the same in terms of components (e.g., facets, sorting, Q&A) and verticalsToConfig (results card, etc), except for any translated strings.

Since all languages will have the default language set as the fallback (in this case English), you could save yourself some time by taking advantage of it!

Here’s how we’d recommend proceeding:

  1. Create your pages using the proper notation [pageName].[languageCode]
  2. Delete the pages/html.hbs file for all pages except the default language
  3. In the config/json file for each non-default language, only specify verticalKey and pageTitle (optionally you can also specify the metaDescription, canonicalUrl or keywords if relevant).
  4. If you need to modify any translations, add those in your top-level translation file for the language (more on that in the next unit)

Here’s what the file directory would look: scenario 1 - file directory

Here’s what the config/faqs.fr.json file would look: scenario 1 - faqs.fr.json file example

Example 2 - Site with 3 languages that have same verticals but want to use different cards/components

Let’s say you’re having trouble getting some data for some languages – not the core stuff, but extra fields like the Product Category which you’re using as a Facet on the Products vertical or the Location Services that you’re displaying on the result cards for Locations.

This example different from above in that you want the verticals to look or behave differently. In other words, you don’t want to rely on any fallback behavior and you want to make sure that you specify the full layout or config for each page explicitly.

In this case, you would not delete the pages/html.hbs files (or at least not those that you want to differ) and you would keep the full componentSettings and/or verticalsToConfig objects in every config file.

Example 3 - Site with 3 languages that have different verticals by language

Let’s say you don’t have data for all verticals in all languages. You might add data for those languages later, or you might not – but you want to get live anyway. We call this a “jagged site structure”. For this example let’s assume you want:

  • Universal search for all languages
  • Locations for all languages (en, de, fr)
  • Products for some languages (en, fr)
  • FAQ just for one language (en)

In this case, you would just create the pages for the vertical/language combinations that you want to support. Instead of creating 12 pages:

  • 1 universal search x 3 languages
  • 3 verticals x 3 languages

You are only creating 9 pages:

  • 1 universal search x 3 languages
  • 1 vertical x 3 languages for locations
  • 1 vertical x 2 languages for products
  • 1 vertical x 1 language for faqs

Other than that, you would proceed the same as Example 1 if you want the vertical to be the same across languages and proceed the same as Example 2 if you want to change the vertical layout or behavior by language.

Your file directory could look like this:

jagged structure

Multi-Language Cards

In the Theme, there are multi-language versions of the cards that have translations for any strings baked into the card itself. You should use this version of the Theme cards for any multi-language site as a best practice. These have the naming convention of “multilang-[card description]“.

When you fork a card, we would recommend forking a multi-language card if you plan to use it for multiple languages. You can learn more about how to specify your own translations or modify any translations that come with the Theme in the next unit.

unit Quiz
+20 points
Daily Quiz Streak Daily Quiz Streak: 0
Quiz Accuracy Streak Quiz Accuracy Streak: 0
    Error Success Question 1 of 3

    My site is in 4 languages, but I only want to surface the Products vertical in 2 languages and I want one language to have facets and sorting and the other language to have just facets. Is this possible?

    Error Success Question 2 of 3

    Is there a way to use one card but have the hardcoded strings translated?

    Error Success Question 3 of 3

    With Fallback behavior, which of the following scenarios are supported? (Select all that apply)

    Way to go, you passed! 🏁

    You've already completed this quiz, so you can't earn more points.You completed this quiz in 1 attempt and earned 0 points! Feel free to review your answers and move on when you're ready.
1st attempt
0 incorrect