Alert This post is over a year old, some of this information may be out of date.

Using the new multilingual APIs in Modern SharePoint

Currently, the Multilingual page publishing for Modern SharePoint feature is rolling out to first-release tenants. This feature allows you to create pages on communications sites in different languages. These pages get linked to each other, and with a language switcher, you can navigate from language variant to variant.

Info: Microsoft 365 Roadmap status on Multilingual page publishing for Modern SharePoint: https://www.microsoft.com/en-us/microsoft-365/RoadmapFeatureRSS/50217.

Multilingual support on Modern SharePoint is a long-awaited feature for many companies, but can you bind your solutions into it? That is exactly what I want to find out once this feature became testable on my tenant.

Configuration

Documentation for this feature is already available on the following page: create multilingual communication sites, pages, and news.

Language switcher
Language switcher

Once you activated your languages, you can start testing out the feature by creating pages.

Lanuage translation options
Lanuage translation options

But how does it all work?

Internally it is a straightforward system. Each site will contain a default language, and this is the language you specified while creating the site collection. In my example, this is English.

As there is one primary language, SharePoint initiates all translations from that one. It is somewhat similar to variations in the past, but it is working a lot better today.

Why is that primary language important?

Each page on a new multilingual enabled site will have the following internal fields related to translations:

  • _SPIsTranslation: Specifies if the current page is a translated page
  • _SPTranslatedLanguages: Specifies which languages are available for the page
  • _SPTranslationLanguage: The page language
  • _SPTranslationSourceItemId: The Unique ID of the source page

These fields are essential to know which languages are available, and also to fetch the other links, but depending if you are on a source page (the primary language) and the page translations.

Source page metadata

The source page metadata looks as follows:

1
2
3
4
5
6
7
{
  "_SPIsTranslation": "No",
  "_SPIsTranslation.value": "0",
  "_SPTranslatedLanguages": ["nl-nl", "fi-fi", "de-de", "fr-fr"],
  "_SPTranslationLanguage": "",
  "_SPTranslationSourceItemId": ""
}

Relevant here is that the current page is not a translated page, and has the following languages available: NL, FI, DE, and FR. For this page, the _SPIsTranslation and _SPTranslatedLanguages are the two critical fields.

Page translation metadata

The metadata of a page translation looks as follows:

1
2
3
4
5
6
7
{
  "_SPIsTranslation": "Yes",
  "_SPIsTranslation.value": "1",
  "_SPTranslatedLanguages": "",
  "_SPTranslationLanguage": "fi-fi",
  "_SPTranslationSourceItemId": "{07EF5378-90FF-4560-AF28-E0A759DDBAF4}"
}

In this metadata, you see a couple of differences. First, the _SPIsTranslation field specifies that the page is a translation instead of a source page, and the link to the source page can be retrieved via the unique ID: _SPTranslationSourceItemId.

So what is the process here

As you can see, everything starts from the source page. If you want to know if the page has linked translations, you can check this in the _SPTranslatedLanguages. When the value is empty, there are no translations for the current page.

On a translated page, you need to check the translations via the _SPTranslationSourceItemId property.

If you want to build a custom solution on top of this, you will first have to do a check to see if it is a source page or translated page. On translated pages, you will have to do an extra call to retrieve all the linked pages.

The APIs

As explained above, you will need to do a couple of calls to know if your control is loaded on the source page or translated page.

Retrieving the translation metadata

You can retrieve the translation metadata by calling the RenderListDataAsStream endpoint for the SitePages library: https://tenant.sharepoint.com/sites/sitename/_api/web/GetList(@listUrl)/RenderListDataAsStream?@listUrl='/sites/sitename/SitePages. This API needs to be called via a POST request with the following body:

1
2
3
4
5
{
  "parameters": {
    "ViewXml": "<View Scope=\"RecursiveAll\"><ViewFields><FieldRef Name=\"_SPIsTranslation\" /><FieldRef Name=\"_SPTranslatedLanguages\" /><FieldRef Name=\"_SPTranslationLanguage\" /><FieldRef Name=\"_SPTranslationSourceItemId\" /></ViewFields><Query><Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Number\">19</Value></Eq></Where></Query><RowLimit /></View>"
  }
}

Info: more information to use the RenderListDataAsStream API can be found here: Using the SharePoint RenderListDataAsStream API to fetch lookup and single managed metadata field values.

Data you get back looks as follows:

RenderListDataAsStream response
RenderListDataAsStream response

Retrieving the available language variants

Once you know if the current page is the source or translation, the next call will be a bit different.

If the current page is the source, you can use the ID of the page to retrieve the metadata, but the best is to use the UniqueId of the page. That way, the experience will be similar to the source and translations.

The call you need to perform to know all translations is: https://tenant.sharepoint.com/sites/sitename/_api/sitepages/pages/getByUniqueId('<UniqueId>')?$select=Path,Version,Translations&$expand=Translations.

Translations response
Translations response

Highlighted in the above screenshot is the metadata you need to know which languages are available and their page URL.

Info: If you want, you can also call https://tenant.sharepoint.com/sites/sitename/_api/sitepages/pages/getByUniqueId('<UniqueId>')/Translations, but this will only give you the available translations and not the source page.

Creating page translations

The creation process is also something you can do from your components. You can use the following API endpoint for this: https://tenant.sharepoint.com/sites/sitename/_api/sitepages/pages(<Source page ID>)/translations/create.

Important: You need to call the API from the source page ID.

The request body looks as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "request": {
    "__metadata": {
      "type": "SP.TranslationStatusCreationRequest"
    },
    "LanguageCodes": {
      "results": ["nl-nl"]
    }
  }
}

Info: the LanguageCodes results is an array of the languages for which you want to create translations. If you specify an empty array [], it creates all language pages at once. In my example, it would be NL, DE, FI, and FR. If you want to create an individual or a couple of pages, you can pass in the language code like: ["nl-nl"] or ["nl-nl", "fi-fi"].

Translation creation API sample
Translation creation API sample

How to know which translations are possible?

You can only translate pages to the selected languages for the site. Otherwise, the create API will error out.

To know the untranslated languages, you can use the same API as you used for retrieving the page variants: https://tenant.sharepoint.com/sites/sitename/_api/sitepages/pages/getByUniqueId('<UniqueId>')?$select=Path,Version,Translations&$expand=Translations.

Untranslated languages
Untranslated languages

You can retrieve languages that are available for translation from the UntranslatedLanguages property.

Veel plezier met vertalen (or have a lot of fun with translating)

Comments

Back to top