返回整合
react-i18next

整合React i18next與 Storybook 整合

React i18next 是一個國際化函式庫,用於本地化應用程式。
先決條件

在開始之前,請確保您有一個使用 react-i18next 的 React 應用程式,並且已設定 Storybook 6.0 或更新版本。如果您需要設定這些的資源,我在下面提供了一些建議

或者,如果您喜歡影片,請觀看 Chantastic's 精彩影片,了解如何將 i18next 新增至您的 React 應用程式。

1. 將 i18next 暴露給 Storybook

為了讓您的翻譯在 Storybook 故事中可用,您首先需要將您的 i18next 實例暴露給 Storybook。這是一個來自 ./src/i18n.js 檔案的 i18next 實例範例,該實例正在我的 React 應用程式中使用。

// src/i18n.js
 
import i18n from 'i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
 
i18n
  .use(Backend) // lazy loads translations from /public/locales
  .use(LanguageDetector) // detect user language
  .init({
    fallbackLng: 'en',
    debug: true,
    interpolation: {
      escapeValue: false,
    },
  });
 
export default i18n;

為了將此實例暴露給 Storybook,我們可以將其匯入到 ./.storybook/preview.js 檔案中,Storybook 在此檔案中保存其共用的故事設定。

// .storybook/preview.jsx
 
import i18n from '../src/i18n';

2. 使用 i18next 提供器包裝您的故事

現在 Storybook 可以存取 i18next 了,我們需要與我們的故事分享它。為此,我們將建立一個裝飾器來包裝我們的故事。

// .storybook/preview.jsx
 
import React, { Suspense } from 'react';
import { I18nextProvider } from 'react-i18next';
import i18n from '../src/i18n';
 
// Wrap your stories in the I18nextProvider component
const withI18next = (Story) => {
  return (
    // This catches the suspense from components not yet ready (still loading translations)
    // Alternative: set useSuspense to false on i18next.options.react when initializing i18next
    <Suspense fallback={<div>loading translations...</div>}>
      <I18nextProvider i18n={i18n}>
        <Story />
      </I18nextProvider>
    </Suspense>
  );
};
 
// export decorators for storybook to wrap your stories in
export const decorators = [withI18next];

太棒了!我們的故事現在正式可以存取我們的翻譯了。如果我們變更 ./src/i18n.js 中定義的 lng,您將看到您的故事以新語言重新載入。

Manually changing the locale from English to French

3. 新增語言環境切換器

硬式編碼您的語言環境很麻煩,而且對於任何查看您已部署 Storybook 的人來說都沒有幫助,因此讓我們將語言環境切換器新增至 Storybook 工具列。如果您想了解更多關於切換器的資訊,請查看 Yann Braga’s 關於新增主題切換器的文章。

為了做到這一點,我們可以在 .storybook/preview.js 中宣告一個名為 locale 的全域變數,並將其指派給一個可供選擇的支援語言清單。

// .storybook/preview.jsx
 
/* Snipped for brevity */
 
// Create a global variable called locale in storybook
// and add a menu in the toolbar to change your locale
export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'en', title: 'English' },
        { value: 'de', title: 'Deutsch' },
      ],
      showName: true,
    },
  },
};

回顧 Storybook,我們現在可以看到工具列中新增了一個「語言環境」切換器,其中包含我們剛剛設定的選項。

The locale switcher in the Storybook toolbar

現在讓我們更新我們的裝飾器,以便在我們選擇新語言時變更我們的語言環境。

// .storybook/preview.jsx
 
/* Snipped for brevity */
 
const withI18next = (Story, context) => {
  const { locale } = context.globals;
 
  // When the locale global changes
  // Set the new locale in i18n
  useEffect(() => {
    i18n.changeLanguage(locale);
  }, [locale]);
 
  return (
    <Suspense fallback={<div>loading translations...</div>}>
      <I18nextProvider i18n={i18n}>
        <Story />
      </I18nextProvider>
    </Suspense>
  );
};

瞧!一個功能完善的語言環境切換器,適用於您的由 react-i18next 驅動的故事!

Switching between English and German using the locale switcher

4. 設定文件方向

有些語言不像英文那樣從左到右讀取。例如,阿拉伯文是從右到左讀取的。HTML 透過 dir 屬性內建了對此的支援。

首先,讓我們透過將一個物件新增到 globalTypesitems 陣列中,將阿拉伯文新增為我們語言環境切換器中的一個選項。

// .storybook/preview.jsx
 
/* Snipped for brevity */
 
// Create a global variable called locale in storybook
// and add a menu in the toolbar to change your locale
export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'en', title: 'English' },
        { value: 'de', title: 'Deutsch' },
        { value: 'ar', title: 'عربي' },
      ],
      showName: true,
    },
  },
};

使用 i18next 的 dir(lng) 函數和 languageChanged 事件,我們可以為選定的語言環境設定文件方向。

// .storybook/preview.jsx
 
/* Snipped for brevity */
 
// When The language changes, set the document direction
i18n.on('languageChanged', (locale) => {
  const direction = i18n.dir(locale);
  document.dir = direction;
});

現在,當我們將 Storybook 設定為阿拉伯文時,文件方向會設定為 「rtl」 🎉

Switching between English, German, and Arabic with the locale switcher

標籤
貢獻者
  • shaunlloyd
    shaunlloyd