Tailwind Logo

Adjusting the sxastarter sample for use on multilingual sites - Part 1-1 Navigation

XM CloudHeadless SXA

Published: 2024-09-12

Since sxastarter, the XM Cloud sample, is designed to create a site in one language, a few adjustments are required to run a site in multiple languages. We will introduce this part in two parts in this issue.

Prerequisite.

In this case, we assume that language fallback has already been applied as a prerequisite. Even if language fallback is not used, it is possible to check the component implementation by adding the ja-JP and en-US languages.

Check browser behavior

We will check how the URL changes depending on the language setting of the browser. To check the operation, access https://www.sxastarter.localhost/.

The results are as follows.

Browser locale

URL

ja-JP

https://www.sxastarter.localhost/ja-JP

en-US

https://www.sxastarter.localhost/en-US

en

https://www.sxastarter.localhost/

fr-fr

https://www.sxastarter.localhost/

As shown above, accessing / will result in English content, and browsers set to Japanese and American English locales will be given the respective URLs.

We have confirmed that en is the standard language, but we will now check the behavior when this is changed to ja-JP. First, change the value of DEFAULT_LANGUAGE of the site deployed in Vercel to ja-JP.

xmcaddlanguage04.png

After the configuration changes, Redeploy is executed to access the site. The result and specification are as follows.

  • Before change
    • https://sitecoredemo.jp/ View English language content
    • Japanese is displayed at https://sitecoredemo.jp/ja-JP
  • After change
    • https://sitecoredemo.jp/ Display Japanese content
    • English is displayed at https://sitecoredemo.jp/en

We have confirmed that changing the default language setting in this way changes the URL for displaying the language.

Get locale

Is it possible to get the locale in a standard component? First of all, let's add the following line to the Default function of the Navigation component (src\sxastarter\src\components\Navigation.tsx).

TypeScript
  console.log(sitecoreContext);

After you have described, for example, accessing https://www.sxastarter.localhost/en-US, you will see that you are getting the following Json data.

JSON
{
  route: {
    name: 'Home',
    displayName: 'Home',
    fields: {
      Content: [Object],
      Title: [Object],
      NavigationTitle: [Object],
      NavigationClass: null,
      NavigationFilter: [],
      SxaTags: [],
      'Page Design': null
    },
    databaseName: 'master',
    deviceId: 'fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3',
    itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
    itemLanguage: 'en-US',
    itemVersion: 1,
    layoutId: '96e5f4ba-a2cf-4a4c-a4e7-64da88226362',
    templateId: '504f30e9-71ae-42fe-9f81-b5006338d516',
    templateName: 'Page',
    placeholders: {
      'headless-header': [Array],
      'headless-main': [Array],
      'headless-footer': [Array]
    }
  },
  itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
  pageEditing: false,
  site: { name: 'sxastarter' },
  pageState: 'normal',
  editMode: 'chromes',
  language: 'en-US',
  itemPath: '/',
  variantId: '_default'
}

If you access the site in en locale or any other language, the following Json will be returned.

JSON
{
  route: {
    name: 'Home',
    displayName: 'Home',
    fields: {
      Content: [Object],
      Title: [Object],
      NavigationTitle: [Object],
      NavigationClass: null,
      NavigationFilter: [],
      SxaTags: [],
      'Page Design': null
    },
    databaseName: 'master',
    deviceId: 'fe5d7fdf-89c0-4d99-9aa3-b5fbd009c9f3',
    itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
    itemLanguage: 'en',
    itemVersion: 1,
    layoutId: '96e5f4ba-a2cf-4a4c-a4e7-64da88226362',
    templateId: '504f30e9-71ae-42fe-9f81-b5006338d516',
    templateName: 'Page',
    placeholders: {
      'headless-header': [Array],
      'headless-main': [Array],
      'headless-footer': [Array]
    }
  },
  itemId: '32b9a0f1-52bd-40b0-adc3-e3bb2397b50d',
  pageEditing: false,
  site: { name: 'sxastarter' },
  pageState: 'normal',
  editMode: 'chromes',
  language: 'en',
  itemPath: '/',
  variantId: '_default'
}

As a result, we were able to confirm that sitecoreContext.language contains the language information that has been set in the content.

Adjusting URL

First, in the Navigation component, we will configure the following URLs to generate links.

  • When ja-JP and en-US are returned, add the respective locale as the URL of the link
  • If en is returned, do not add a locale

In the Navigation component (src\sxastarter\src\components\Navigation.tsx), a type definition is given in the form of NavigationProps as link information. Add a locale to this.

TypeScript
type NavigationProps = {
  params?: { [key: string]: string };
  fields: Fields;
  handleClick: (event?: React.MouseEvent<HTMLElement>) => void;
  relativeLevel: number;
  locale: string;
};

The path is not added to this locale if sitecoreContext.language is en or undefined, but is added as a URL if it is ja-JP or en-US.

The following code is used for this part of the process.

TypeScript
const getLocale = function (props: SitecoreContextValue): string {
  let locale;

  if (!props.language || props.language === process.env.DEFAULT_LANGUAGE) {
    locale = '';
  } else {
    locale = '/' + props.language;
  }

  return locale;
};

The function returns the root if English, otherwise the locale URL. Using the function with the additions, the default is to pass sitecoreContext to set contentLocale.

TypeScript
  const contentLocale = getLocale(sitecoreContext);

Then, at the point where NavigationList is called, pass the locale as follows

TypeScript
      <NavigationList
        key={`${key}${element.Id}`}
        fields={element}
        handleClick={(event: React.MouseEvent<HTMLElement>) => handleToggleMenu(event, false)}
        relativeLevel={1}
        locale={contentLocale}
      />

As for NavigationList, we are making a recursive call to ourselves, so the code is written in such a way that the value is inherited.

TypeScript
  if (props.fields.Children && props.fields.Children.length) {
    children = props.fields.Children.map((element: Fields, index: number) => (
      <NavigationList
        key={`${index}${element.Id}`}
        fields={element}
        handleClick={props.handleClick}
        relativeLevel={props.relativeLevel + 1}
        locale={props.locale}
      />
    ));
  }

Now we have implemented the passing of the locale as a value. Now we need to implement this value as a URL by adding information about the locale in the getLinkField code used to generate the URL.

TypeScript
const getLinkField = (props: NavigationProps): LinkField => ({
  value: {
    href: props.locale + props.fields.Href,
    title: getLinkTitle(props),
    querystring: props.fields.Querystring,
  },
});

This completes the URL adjustment.

Operation check

Go to the site and check the URL. The following screen shows the changed URL and confirms that the locale has been correctly added to the URL.

xmcaddlanguage02.png

Summary

This time, we used the Navigation component to introduce how to configure URLs on a multilingual site and how to adjust URLs output by components, although the URLs to be displayed are adjusted.

There are several standard components, but covering them all would be too long, so we have only introduced Navigation in this issue. In the next issue, we will introduce other components.

Tags