在我们开始之前,请确保您有一个使用 react-i18next
的 React 应用程序,并且该应用程序已使用 Storybook 6.0 或更高版本进行设置。如果您需要设置这些的资源,我在下面列出了一些推荐。
或者,如果您更喜欢视频,请查看 Chantastic 的精彩视频,介绍如何将 i18next 添加到您的 React 应用程序中。
要使您的翻译在您的故事中可用,您首先需要将您的 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';
现在 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
,您将看到您的故事以新语言重新加载。
硬编码您的语言环境很烦人,对查看您已部署的 Storybook 的任何人来说都没有帮助,所以让我们在 Storybook 工具栏中添加一个语言切换器。如果您想了解有关切换器的更多信息,请查看 Yann Braga 的关于 添加主题切换器 的文章。
为此,我们可以声明一个名为 locale
的全局变量,在 .storybook/preview.js
中将其分配给要从中选择的支持语言列表。
// .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,我们现在可以看到我们在工具栏中添加了一个“语言环境”切换器,其中包含我们刚刚设置的选项。
现在让我们更新我们的装饰器,以便当我们选择一种新语言时更改我们的语言环境。
// .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 提供支持的,用于您的故事的完全正常运行的语言切换器!
有些语言不像英语那样从左到右阅读。例如,阿拉伯语是从右到左阅读的。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”
🎉