🧚‍♀️

React Server Components 多言語対応の実装例

4 min read
graph TB
    D[ リモートワーカーの地位を向上 ] --> C
    E[ エンジニアリングの本質を追求 ] --> C 
    C[ VTEACHER の MISSION ]

こちらも参考に

https://zenn.dev/rgbkids/articles/7cbb158c52781d

React Server Componentsの多言語対応

react-intl や react-i18next が有名ですが、ここはあえて、React Server Componentsの恩恵をうけるために、react-i18nextライクな自作関数を作成し、サーバー側で利用できる形にしてみます。

実装したものを、実際にさわってみてください。言語(🇺🇸🇯🇵🇹🇼🇰🇷)を切り替えられます。

https://studywithme.cmsvr.live/

一度国旗をクリックしたら、サイドバーで動画を選んでもその言語を選択しています。
lang はAppの状態(location)に追加してあります。

使い方

  • 言語選択画面の表示(クライアントコンポーネント)
<Language />
  • 指定言語のメッセージを表示
{t("HOW_TO_ADD", lang)}

設定

export const language_resources = {
    en: {
        translation: {
            SIGN_IN_TEXT: 'Sign in - Google Accounts',
            SIGN_OUT_TEXT: '✋Sign out',
            HOW_TO_ADD: 'Click ➕, select the users you want to study with from the sidebar.',
            HOW_TO_WATCH: 'Play live streams at the same time!',
            START_TOGETHER: 'STUDY WITH ME!',
            HOW_TO_LIVE: 'You can stream STUDY WITH ME on VTeacher.',
            ABOUT_HASHTAG: '( Live streaming with #STUDYWITHME hashtag )',
            DOWNLOAD_APP: 'Download on App Store',
        },
    },
    ja: {
        translation: {
            SIGN_IN_TEXT: 'まずは Sign in - Google Accounts',
            SIGN_OUT_TEXT: '✋Sign out',
            HOW_TO_ADD: 'サイドバーから一緒に勉強したいユーザーを➕',
            HOW_TO_WATCH: 'ライブ配信を同時に再生しよう!',
            START_TOGETHER: 'STUDY WITH ME! いっしょに勉強しよう!',
            HOW_TO_LIVE: 'VTeacherでSTUDY WITH MEの配信ができます',
            ABOUT_HASHTAG: '( #STUDYWITHME のハッシュタグをつけて配信 )',
            DOWNLOAD_APP: 'App Storeでダウンロード',
        },
    },
    zh_cmn_Hant: {
        translation: {
            SIGN_IN_TEXT: 'Sign in - Google Accounts',
            SIGN_OUT_TEXT: '✋Sign out',
            HOW_TO_ADD: '單擊 ➕,從側邊欄中選擇要與之一起學習的用戶。',
            HOW_TO_WATCH: '同時播放直播!',
            START_TOGETHER: '跟我一起學習!',
            HOW_TO_LIVE: '您可以在 VTeacher 上直播 STUDY WITH ME。',
            ABOUT_HASHTAG: '(使用#STUDYWITHME 標籤進行直播)',
            DOWNLOAD_APP: '在 App Store 下載',
        },
    },
    ko: {
        translation: {
            SIGN_IN_TEXT: 'Sign in - Google Accounts',
            SIGN_OUT_TEXT: '✋Sign out',
            HOW_TO_ADD: '➕을 클릭하고 사이드바에서 함께 공부할 사용자를 선택합니다.',
            HOW_TO_WATCH: '동시에 라이브 스트림을 재생합니다!',
            START_TOGETHER: '저와 함께 공부하세요!',
            HOW_TO_LIVE: 'VTeacher에서 STUDY WITH ME를 스트리밍할 수 있습니다.',
            ABOUT_HASHTAG: '( #STUDYWITHME 해시태그와 함께 라이브 스트리밍 )',
            DOWNLOAD_APP: '앱 스토어에서 다운로드',
        },
    },
};

使用例のコード

サーバーコンポーネントで処理をしているので、言語用の設定ファイルの行数が多くても(サイズ容量が大きくても、計算量が多くても)、クライアントのパフォーマンスに考慮した形になっています。

※言語選択時にlocationを設定しています。リロード用にlocalStorageへ保存しています。

実験: React Server Componentsの恩恵を受けてみる

実験として設定ファイルのサイズ量を意図的に増やしてみましょう。
たとえば、画像ファイルをテキストにし(base64)、settings.jsに貼り付けておきましょう。複雑な計算式を加えることも良しです。

-rw-r--r--  1 root root 806834 Oct 13 08:11 settings.js
-rw-r--r--  1 root root   3174 Oct 13 08:00 settings.js.bkup

指定言語のメッセージ表示を、サーバーコンポーネントで実行する場合と、クライアントコンポーネントで実行する場合を比較してみましょう。

準備ができたら、言語(🇺🇸🇯🇵🇹🇼🇰🇷)を切り替えてみましょう。
Chromeの開発ツールからネットワークをみてみましょう。

https://studywithme.cmsvr.live/react?location=...(略)

サイズはsettings.jsよりも、かなり小さいサイズになっていると思います。
React Server Componentsですから、サーバーコンポーネントで実行する場合のほうが、クライアント側のパフォーマンスが良くなります。
(サーバーサイドとのトレードオフとも言えます)

Discussion

ログインするとコメントできます