Caching - Dictionary Service in Sitecore-JSS

Caching - Dictionary Service in Sitecore-JSS

I outlined the below?scenario in a?previous post. In this article, we will focus on performance improvement.

"Default, you might observe that your JSS application, built using the Sitecore starting template, requests data from /Sitecore/API/dictionary each time a page loads.

Knowing that Sitecore dictionaries are pretty static and that client-side queries are made regardless of whether your application is running headless or integrated with SSR,?it is not just an ideal choice."

The starter?template has a suggestion?in?/src/i18n.js file to cache the dictionary data.

Install the packages i18next-chained-backend, i18next-localstorage-backend, and i18next-fetch-backend (if not previously installed).

npm install i18next-chained-backend
npm install i18next-localstorage-backend
npm install i18next-fetch-backend        
Note: i18next.js is a translation module. It may be difficult to understand if you are not familiar with it. Simply adhere to the guidelines.

Replace the following code in the src/i18n.js file after installing the packages. With this modification, the dictionary data will be cached in local storage for 10?minutes.

import i18n from 'i18next';
// eslint-disable-next-line import/no-extraneous-dependencies
import backend from 'i18next-chained-backend';
// eslint-disable-next-line import/no-extraneous-dependencies
import localStorageBackend from 'i18next-localstorage-backend';
// eslint-disable-next-line import/no-extraneous-dependencies
import fetchBackend from 'i18next-fetch-backend';
import { initReactI18next } from 'react-i18next';
import { dictionaryServiceFactory } from './lib/dictionary-service-factory';
import config from './temp/config';
/**
 * Initializes the i18next library to provide a translation dictionary to the app.
 * If your app is not multilingual, this file and references to it can be removed.
 * Elsewhere in the app to use the dictionary `import { t } from 'i18next'; ... t('key')`
 * @param {string} language Optional, the initial language. Only used for SSR; otherwise language set in RouteHandler.
 * @param {*} dictionary Optional, the dictionary to load. Only used for SSR; otherwise, the dictionary is loaded via JSS dictionary service.
 */
export default function i18nInit(language, dictionary) {
  return new Promise((resolve, reject) => {
    const options = {
      debug: false,
      lng: language,
      fallbackLng: false, // fallback to keys
      load: 'currentOnly', // e.g. don't load 'es' when requesting 'es-MX' -- Sitecore config should handle this
      useCookie: false, // using URLs and Sitecore to store language context, don't need a cookie

      interpolation: {
        escapeValue: false, // not needed for react
      },
    };

    if (dictionary) {
      // if we got dictionary passed, that means we're in a SSR context with a server-provided dictionary
      // so we do not want a backend, because we already know all possible keys

      if (!i18n.isInitialized) {
        i18n.use(initReactI18next).init(options, (error) => {
          if (error) reject(error);

          i18n.addResourceBundle(language, 'translation', dictionary, true, true);

          resolve();
        });
      } else {
        i18n.changeLanguage(language).then(() => {
          i18n.addResourceBundle(language, 'translation', dictionary, true, true);

          resolve();
        });
      }
    } else {
      // We're running client-side, so we get translation data from the Sitecore dictionary API using fetch backend
      // For higher performance (but less simplicity), consider adding the
      // i18n chained backend to a local cache option like the local storage backend.

      // instantiate the dictionary service.
      const dictionaryServicePath = `${config.sitecoreApiHost}/sitecore/api/jss/dictionary/${config.jssAppName}/{{lng}}?sc_apikey=${config.sitecoreApiKey}`;
      options.backend = {
        backends: [localStorageBackend, fetchBackend],
        backendOptions: [
          {
            prefix: 'jss-dic-translation', // cache prefix use your app name here
            expirationTime: 10 * 60 * 1000, // cache for 10 minutes
          },
          {
            loadPath: dictionaryServicePath,
            parse: (data) => {
              const parsedData = JSON.parse(data);
              if (parsedData.phrases) {
                return parsedData.phrases;
              }
              return parsedData;
            },
          },
        ],
      };
      i18n
        .use(backend)
        .use(initReactI18next)
        .init(options, (error) => {
          if (error) reject(error);

          resolve();
        });
    }
  });
}
        

Start the application in connected mode and reload the page, now you see the dictionary is cached for 10 minutes in local storage.

I've configured a 10-minute cache expiration period in my case, but you may adjust it to suit your needs by changing the highlighted string below.

I hope this post?is useful to you.

Thanks.

要查看或添加评论,请登录

Akif Irfan的更多文章

社区洞察

其他会员也浏览了