Your libero, the SharePoint Framework (SPFx), can be trained to exactly match your needs. I will show what happens when you enable multilingual publishing and how you can train your best player to communicate with your players.

Table of Contents

Technical Impact of Enabling Multilingual Publishing

When you enable Multilingual publishing, SharePoint, among other things, creates the following fields in your Sitepageslibrary :

  • OData__SPIsTranslation
  • OData__SPTranslationLanguage
  • OData__SPTranslationSourceItemId

You will find a lot of valuable informations in these blog posts from Elio Struyf :

Note These fields are not present if you haven’t enable Multilingual publishing.

These fields provide your code with valuable information about the language context of the page.

Align your SPFx Web Part with your page language content

In order to make your webpart behave and render in the content language of your page, you first need to gather the actual page language.

Getting the page language

Page language informations are only accessible when you are viewing a translated page, when you are viewing the default variation of the page, language informations are present but their value is null. In this case, we should use the Site default language.

Note This code uses PnPJs 🔗 and the LCID npm package 🔗

Code Snippet

export interface IPageContext {
    OData__SPIsTranslation?: boolean;
    OData__SPTranslationLanguage?: string;
}

export interface ILanguageRepresentation {
    lcid: number;
    Language: string;
}

public getPageContext = async (listId: string, listItemId: number): Promise<IPageContext> => {
    const context: IPageContext = await this.sp.web.lists.getById(listId)
        .items
        .getById(listItemId)
        .select(
            'OData__SPIsTranslation',
            'OData__SPTranslationLanguage'();
    return context;
}

public calculateLanguage = async (listId: string, listItemId: number, defaultLanguage: number): Promise<ILanguageRepresentation> => {
    // Implementation
    const languageData: ILanguageRepresentation = {
        lcid: 0, 
        Language: ''
    };
    
    try {
        pageContext = await this.getPageContext(listId, listItemId);
    } catch (error) {
        // Log or skip based on your needs
    }
    if (!pageContext || !pageContext.OData__SPIsTranslation || !pageContext.OData__SPTranslationLanguage) {
        // Not running in a multilingual setup => get language from web
        languageData.lcid = this.context.pageContext.web.language;
        languageData.Language = lcid.from(this.context.pageContext.web.language);
        return languageData;
    }
    // Page is a translation => get language from page property
    languageData.lcid = lcid.to(pageContext.OData__SPTranslationLanguage);
    languageData.Language = pageContext.OData__SPTranslationLanguage;
    return languageData;
}

// Call your calculate language method
pageLanguage = await yourclass.calculateLanguage(listId, listItemId);

In the code above:

  • We define interfaces to structure the translation-related information for the page (IPageContext) and the language representation (ILanguageRepresentation).
  • The getPageContext method fetches translation-related fields (OData__SPIsTranslation and OData__SPTranslationLanguage) for a specific list item, which is expected to be a page or a news page.
  • The calculateLanguage method checks if the page is a translation:
    • If not a translation, it retrieves the default language from the web’s language settings.
    • If it is a translation, it uses the translation-specific fields to determine the language.
  • Finally, we call calculateLanguage to retrieve the language details for a given list item.

Taking Control of SPFx

Now that we know how to retrieve the page language, let’s override the default SPFx behavior to serve content in the correct page language.

We’ll implement a method to retrieve the correct localized string based on the stringName and the locale we gathered earlier.

Code Snippet

export class Utility {
  static getStringTranslation4Locale(stringName: string, locale: string): string {
    try {
      const translatedString = require(`../loc/${locale}.js`);
      return translatedString[stringName];
    } catch (error) {
      try {
        const defaultString = require(`../loc/default.js`);
        return defaultString[stringName];
      } catch (defaultError) {
        return `Error: Missing translation file for ${locale} and default locale`;
      }
    }
  }
}

// Retrieving a string for a specific locale
Utility.getStringTranslation4Locale('yourstringname', 'yourlocale');

In the code above:

  • We implement a method that loads the appropriate localization files based on the requested locale.
  • If a translation for the locale exists, it returns the corresponding string.
  • If the string for the specified locale is missing, it falls back to the default locale.
  • If both the locale and default strings are unavailable, it returns an error indicating the missing files.

A few notes:

  • Ensure the path in the require statements is adjusted based on where your Utility class is located in the project.
  • You can extend the logic to support multiple languages or locales, as needed.

Full code implementation

You can find a full implementation in one of the PuntoBello solutions 🔗

Conclusion

With this implementation, you are in full control of how your SPFx Web Parts behave, and you can synchronize your SPFx Web Part language with the page content.