在開始之前,請確保您有一個使用 react-i18next
的 React 應用程式,並已設定 Storybook 6.0 或更新版本。如果您需要設定這些的資源,我已在下方提供一些建議
或者,如果您喜歡影片,請查看 Chantastic 關於在 React 應用程式中新增 i18next 的精彩影片。
為了讓您的翻譯在您的故事中可用,您首先需要將 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 保留其共用故事組態的位置。
// .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 關於新增主題切換器的文章。
為此,我們可以在 .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,我們現在可以看到工具列中新增了一個「地區設定」切換器,其中包含我們剛才設定的選項。
現在,讓我們更新我們的裝飾器,以便在我們選取新語言時變更我們的地區設定。
// .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
屬性內建支援此功能。
首先,讓我們在全域類型項目的陣列中新增一個物件,以將阿拉伯語新增為我們的地區設定切換器中的一個選項。
// .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”
🎉