加入直播会议:美国东部时间周四上午 11 点,Storybook 9 发布及问答
返回集成
react-i18next

集成React i18next与 Storybook 集成

React i18next 是一个用于应用程序本地化的国际化库。
前提条件

在开始之前,请确保你有一个正在运行的 React 应用程序,它使用了 react-i18next 并已配置 Storybook 6.0 或更新版本。如果你需要设置这些的资源,我已经在下面提供了一些建议

如果你更喜欢视频,可以观看 Chantastic 的精彩视频,了解如何在你的 React 应用程序中添加 i18next。

1. 将 i18next 暴露给 Storybook

为了在你的 stories 中使用翻译,首先需要将 i18next 实例暴露给 Storybook。以下是一个在我的 React 应用程序中使用的来自 ./src/i18n.js 文件的 i18next 实例示例。

// 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 在此文件中存放共享的 story 配置。

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

2. 使用 i18next provider 包装你的 stories

现在 Storybook 可以访问 i18next 了,我们需要将其共享给我们的 stories。为此,我们将创建一个装饰器来包装我们的 stories。

// .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];

太好了!我们的 stories 正式可以访问我们的翻译了。如果更改 ./src/i18n.js 中定义的 lng,你会看到你的 stories 以新语言重新加载。

Manually changing the locale from English to French

3. 添加一个语言切换器

硬编码你的语言环境既麻烦又对查看你部署的 Storybook 的人没有帮助,所以我们来在 Storybook 工具栏中添加一个语言切换器。如果你想了解更多关于切换器的信息,请查看 Yann Braga 关于添加主题切换器的文章。

要实现这一点,我们可以在 .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>
  );
};

Voilà!一个由 react-i18next 提供支持的、功能齐全的 stories 语言环境切换器!

Switching between English and German using the locale switcher

4. 设置文档方向

有些语言不像英语那样从左到右阅读。例如,阿拉伯语是从右到左阅读。HTML 通过 dir 属性内置了对此的支持。

首先,通过在 globalTypes 的 items 数组中添加一个对象,将阿拉伯语添加到我们的语言环境切换器选项中。

// .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