Internationalizing Template Labels In SPAs
May 10, 2022
--
Internationalize SPAs 1200x628

Internationalizing Template Labels In SPAs

Internationalization is a key feature when looking for a headless CMS that must handle more than one language version of a website. In the majority of projects, we can distinguish between two groups of translatable text:

  • Editorial content makes for the majority of translatable text. It is the main content on your website created to appeal to and educate your target audience.

  • Template labels are text that is displayed to visitors but it is not editorial content and cannot be changed by content authors. Examples of labels are page breadcrumb labels such as “You are here” and static button text in specific components such as “Login” or “Logout”.

Internationalizing editorial content for headless consumption in Magnolia is very easy. I covered this topic under “Localized content” in my blog Headless Magnolia: The Delivery Endpoint API.

But what about translating template labels in headless Magnolia? In this blog post, I will show you one possible solution using a content app to store translations. Think of it as a digital vocabulary book.

New Content Type

Magnolia Content Types define the content model in Magnolia. Content authors can edit this content in content apps. So, let’s create a Content Type and a content app.

Start by creating a new Magnolia Light Module directory “i18n-lm”.

Once our new Light Module is in place, define a new Content Type “i18n”.

File: /i18n-lm/contentTypes/i18n.yaml

YAML
  datasource:
 workspace: i18n
 autoCreate: true
model:
 properties:
   - name: name
     required: true
   - name: value
     i18n: true

We will store the data in a new workspace called “i18n”. The content model will have two properties:

  • name - the name of the property. Let’s make this required.

  • value - translation text. This property has to have internationalization (i18n) enabled.

Once you created the new Content Type, let Magnolia create a Content App called “i18n” for it.

File: /i18n-lm/apps/i18n-app.yaml

YAML
  !content-type:i18n
name: i18n-app
label: i18n
icon: icon-forums-app
subApps:
 browser:
   workbench:
     contentViews:
       tree:
         columns: !override
           name:
             $type: jcrTitleColumn
             expandRatio: 1
           value:
             expandRatio: 1
           activationStatus:
             $type: jcrStatusColumn
             width: 200

You should now see the new app in Magnolia:

AdminCentral_i18n

Adding Translations

You can now add translations.

I recommend you create a folder first and add translations inside the folder. That way you can group translations by pages.

i18n_content_app

When adding content in the app you can see the language switcher in the bottom-left corner.

i18n_content_app_tab

The languages you see in this list are taken from the default (fallback) language settings in your site definition.

Fetching Data

To fetch the correct translations you can use the Magnolia Delivery API. Create its endpoint first:

File: /i18n-lm/restEndpoints/delivery/i18n.yaml

YAML
  workspace: i18n
bypassWorkspaceAcls: true
limit: 1000
depth: 10
nodeTypes:
 - mgnl:folder
childNodeTypes:
 - mgnl:content

You can now fetch translations in the default locale via /.rest/delivery/i18n/my-page:

YAML
  {
 "@name": "my-page",
 "@path": "/my-page",
 "@id": "100ceaa5-3ee4-47d7-9b8d-621423ef45fd",
 "@nodeType": "mgnl:folder",
 "name": "my-page",
 "foo": {
   "@name": "foo",
   "@path": "/my-page/foo",
   "@id": "135c4be1-3358-4d9b-a566-4a7c40a92261",
   "@nodeType": "mgnl:content",
   "value": "Hey",
   "name": "foo",
   "@nodes": []
 },
 "bar": {
   "@name": "bar",
   "@path": "/my-page/bar",
   "@id": "e85104ac-188a-4a5a-bed8-42abb60ab9ee",
   "@nodeType": "mgnl:content",
   "value": "Bye",
   "name": "bar",
   "@nodes": []
 },
 "@nodes": [
   "foo",
   "bar"
 ]
}

If you want translations in another language, use the URL parameter lang, for example, “de” for German:

/.rest/delivery/i18n/my-page?lang=de

You can use your translations in your app, for example, as an object:

JavaScript
  const i18n = response['@nodes'].reduce((acc, item) => {
 acc[item] = response[item].value;
 return acc;
}, {});

If you need a specific translation you can simply reference the key:

XML/HTML
  <div>{i18n.foo}</div>  

Auto-translating Labels

We can speed up the global rollout through automatically translating all data in the content app using the DeepL Translator from the Magnolia Marketplace.

Once the module is installed, you have to add a new action to your app:

File: /i18n-lm/apps/i18n-app.yaml

YAML
  !content-type:i18n
name: i18n-app
label: i18n
icon: icon-forums-app
subApps:
 browser:
   workbench:
     contentViews:
       tree:
         columns: !override
           name:
             $type: jcrTitleColumn
             expandRatio: 1
           value:
             expandRatio: 1
           activationStatus:
             $type: jcrStatusColumn
             width: 200
   actionbar:
     sections:
       folder:
         groups:
           activationActions:
             items:
               publishRecursive: {}
           i18n:
             items:
               addToTranslationBatch: {}
       item:
         groups:
           activationActions:
             items:
               publishRecursive: {}
           i18n:
             items:
               addToTranslationBatch: {}
   actions:
     # Publishes the selected node and its children to the public instance
     publishRecursive:
       icon: icon-publish-incl-sub
       $type: jcrCommandAction
       command: publish
       asynchronous: true
       params:
         recursive: true
       availability:
         writePermissionRequired: true
         rules:
           isDeletedRule:
             $type: jcrIsDeletedRule
             negate: true
           publishableRule:
             $type: jcrPublishableRule
     # DeepL Translator module https://marketplace.magnolia-cms.com/detail/deepl-translator.html action
     addToTranslationBatch:
       label: Add to translation batch
       dialogName: content-translation-support-ext-core:addToTranslationBatch
       icon: icon-add-folder
       class: info.magnolia.translation.ext.core.app.batch.action.OpenMultiEditDialogAction$Definition
       availability:
         writePermissionRequired: true
         access:
           roles:
             superuser: superuser
         nodeTypes:
           folder: mgnl:folder
           content: mgnl:content
         rules:
           notDeleted:
             $type: jcrIsDeletedRule
             negate: true
         multiple: true
         root: false

Git Repo

By creating a simple Content Type and content app you can enable your content authors to manage the translation of labels. If you want to implement this solution yourself, you can find the code examples on Git.

About the author

Bartosz Staryga

Front-End Solution Architect, Magnolia

Bartosz is an expert in headless content management and front-end development at Magnolia. He designs and develops new Magnolia features and supports customers with their headless implementations from content types to APIs to integrations. Bartosz enjoys building new things and seeing them in action. He is also a trainer for Magnolia’s Headless training.