著者:
    作成:2026-09-13最終更新:2026-09-22

    next-intl VS @intlayer/next-intl:同じAPI、異なるBundle

    next-intl VS Intlayer

    @intlayer/next-intl は互換性アダプタです。next-intl API (useTranslations、getTranslations、useLocale、t.rich()、ICU複数形、NextIntlClientProvider...)を公開し、Intlayerによってコンパイルされたディクショナリから提供します。アプリケーションコードは変わりません。bundleが変わります。

    この記事は、同じNext.jsアプリケーションで2つを比較しており、1回はnext-intlで構築し、もう1回はアダプタで構築しています。数値はBenchmark Bloomから得られており、これはブラウザが実際にダウンロードするものを記録するオープンソーススイートです。ライブラリとしてnext-intlとIntlayerの比較が必要な場合は、next-intl vs Intlayerをお読みください。このドキュメントは、コンポーネントをそのままにしておいたときにアダプタが何を変更するかについてです。

    tl;dr: 同じNext.jsアプリで、next-intlを@intlayer/next-intlに置き換えることで、ページあたりのJavaScriptが153.6 KBから147.5 KB gzipに、平均コンポーネントが21.8 KBから8.1 KBに、外部ページの文字列漏洩が約90%から0%に、ハイドレーションが14.7 msから12.8 msに短縮され、コンポーネント編集なしで達成されました。TanStack Startでは、use-intlの同等物(@intlayer/use-intl)がコンポーネントを76-87 KBから9-11 KBに削減し、ロケール切り替えを7-21 msから4-9 msに短縮しました。アダプターのランタイムコストは8.0 KB(next-intlは14.7 KB、ネイティブnext-intlayerは5.5 KB)です。ナビゲーションとミドルウェアはIntlayerのルーティング設定で再実装されます。ローカライズされたpathnamesは唯一引き継がれない機能です。

    @intlayer/next-intlとは何か

    next-intl はランタイムです: getRequestConfig はリクエストごとに messages/{locale}.json を読み込み、NextIntlClientProvider がそれをクライアントに送り、useTranslations("about") がレンダリング時にそのオブジェクトからキーを読み込みます。すべての最適化(名前空間、ページごとの pick(messages, [...])、遅延読み込み)はあなたが書く必要があります。

    @intlayer/next-intl はそのチェーンの最初と最後の部分を保つ代わりに、中間部分を置き換えます。あなたのコンポーネントは依然として useTranslations("about") を呼び出しますが、受け取る内容はビルド時にコンパイルされた Intlayer 辞書から来ており、そのコンポーネントにスコープされ、アクティブなロケールのみが含まれます。

    3 つのメカニズムでこれを実現します:

    1. Import aliasing. createNextIntlPlugin() from @intlayer/next-intl/plugin は withIntlayer をラップし、Webpack / Turbopack aliases を追加します。これにより、next-intl、next-intl/server、next-intl/navigation、next-intl/middleware が @intlayer/next-intl に解決されます。codebase 内のいかなる import も変更されません。
    2. JSON as source of truth. syncJSON plugin は既存の messages/{locale}.json を読み取り、その top-level keys を namespace ごとに 1 つの dictionary に分割し、CLI または CMS がそれらを更新する際に同じファイルに翻訳を書き込みます。translator のワークフローは変わりません。
    3. Call-site binding。 Intlayer optimize pass (Babel または SWC) は useTranslations("about") を、about dictionary を直接受け取る呼び出しに書き換えます。コンポーネントはもはやグローバルメッセージツリーにアクセスせず、自身のコンテンツにアクセスします。
    app/[locale]/about/page.tsx
    // あなたのコード、変更なし
    import { useTranslations } from "next-intl";
    
    const AboutPage = () => {
      const t = useTranslations("about");
      return <h1>{t("title")}</h1>;
    };
    
    What the compiler emits (simplified)
    // コンパイラが出力するもの (簡略版)
    import _dicHash_about from "../.intlayer/dictionaries/about.mjs";
    import { useDictionary as useTranslations } from "@intlayer/next-intl";
    
    const AboutPage = () => {
      const t = useTranslations(_dicHash_about);
      return <h1>{t("title")}</h1>;
    };
    

    そのリライトが、以下のコンポーネントサイズとページリーケージのカラムが移動する理由です:ページは、それがレンダリングするコンポーネントの辞書のみを取得し、提供されているロケールでのみ取得します。

    アダプターが保持、無視、および置き換えないもの

    next-intl API@intlayer/next-intlを使用している場合
    useTranslations("ns") / getTranslations("ns")✅ 保持。ビルド時にns辞書にバインドされます。キーはコンテンツに対して型付けされます。
    getTranslations({ locale, namespace })✅ 保持されています
    t("key", { name }), t.rich(), t.markup(), t.raw()✅ 保持されています。ICU plurals、select、selectordinal、#、{ts, date, long} は Intlayer の ICU resolver を通じて実行されます
    useLocale() / getLocale() / setRequestLocale() / setLocale✅ 保持されています
    useFormatter()✅ 保持されています。dateTime、number、relativeTime、list、dateTimeRange はネイティブな Intl へ橋渡しされます
    NextIntlClientProvider✅ 維持。messages、timeZone、now プロップは受け入れられていますが無視されます(開発者向け警告が表示されます)
    getMessages()✅ 互換性のため維持;もう必要ありません
    getRequestConfig() in src/i18n.ts⚠️ 不要。辞書はビルド時にコンパイルされます;リクエストごとのメッセージ読み込みはありません
    defineRouting()✅ 維持。省略されたフィールド(locales、defaultLocale、localePrefix)は intlayer.config.ts から読み込まれます
    createNavigation(), Link, redirect, usePathname, useRouter✅ 保持。Intlayer のルーティング設定で再実装されます。routing 引数は受け入れられていますが無視されます
    pathnames (ローカライズされたルート名)❌ 型指定用に受け入れられます。補間されません。プレーンパス名を保つか、そのマッピングを Intlayer の rewrite に移動してください
    createMiddleware()✅ 保持。Intlayer のプロキシを返します。NEXT_LOCALE cookie を設定するので、useLocale() とあなたのスイッチャーは機能し続けます
    NEXT_LOCALE cookie✅ デフォルトで読み込まれます(routing.storage を自分で設定しない限り)
    Bare useTranslations() with no namespace⚠️ 動作しますが、呼び出しサイトがバインドされていません: ランタイムレジストリを通じて解決されます。バンドルの利得を得るには namespace を渡してください

    ベンチマーク

    測定内容

    Benchmark Bloom スイートは、各セットアップで同じアプリケーションをビルドします: 10 ページ (home、about、blog、careers、contact、FAQ、pricing、products、settings、team)、10 locales (en、fr、es、de、it、pt、zh、ja、ko、ru)、同一のコンポーネントと同一のコンテンツ。ページは en と fr で測定されます。

    next-intlは4つのローディング戦略で構築されました。単純なセットアップ(messages/{locale}.json全体を読み込む)から最適なもの(ルートごとに1つのnamespace + ページごとのpick())まで。アダプターは単純なセットアップと同じコンポーネントで構築され、next.config.tsとintlayer.config.tsのみが変更されました。「scoped」バリアントはありません。コンパイラがコンポーネントごとにコンテンツをスコープするため、staticとdynamicの行はすでにスコープされています。

    各ビルドについて、スイートは以下を記録します:

    • Lib size: i18nライブラリのみをインポートする空のコンポーネントのgzipサイズ。ランタイムの固定コスト。
    • Page JS: ページごとにダウンロードされるgzip JavaScript。すべてのページとロケールで平均化されます。
    • ロケールリーク %: ダウンロードされた JS に含まれる翻訳済み文字列のうち、ユーザーが表示していないロケールに属する文字列の割合。
    • ページリーク %: ダウンロードされた JS に含まれる翻訳済み文字列のうち、ユーザーが閲覧していないページに属する文字列の割合。
    • Component avg: 個別にコンパイルされた各コンポーネントの平均 gzip サイズ。単一のコンポーネントが i18n ランタイムとカタログにどの程度のオーバーヘッドをもたらすかを示します。
    • E2E reactivity: 新しいロケールを選択してから DOM の html[lang] が更新されるまでの実際の時間 (Playwright、5 回のイテレーション)。
    • Hydration: React ハイドレーション フェーズの継続時間。
    以下の数値は 2026-09-12 に実施した実行結果です。next-intl / use-intl 4.14.2 および @intlayer/* 9.5.1 を使用しています。テストアプリケーションは意図的に小規模(ロケールあたり数十の文字列)であるため、リーケージのパーセンテージはパターンを説明しています。コンテンツが増えるにつれてリーケージは増加しますが、runtime のコストは固定のままです。

    Next.js での結果

    関心のある指標とライブラリを選択してください:

    指標

    動的な JSON 読み込み

    実行時に翻訳を遅延読み込みします

    スコープ付き JSON (ネームスペース)

    ページごとの翻訳ネームスペース

    この指標は何ですか?

    国際化ライブラリバンドルの合計gzip圧縮サイズ。これには、ツリーシェイキングと縮小化(minification)後のプロバイダーとコンテンツ取得ロジックのみが含まれます。

    なぜ重要なのか?

    ライブラリのサイズが小さければ初期 JavaScript ペイロードが削減され、クライアント側でのダウンロードと実行が高速化されます।

    表示形式

    SetupStrategyLib size (gz)Page JS avg (gz)Locale leakPage leakComponent avg (gz)E2E reactivityHydration
    base (no i18n)-0.0 KB141.0 KB0.0%0.0%0.9 KB13.4 ms11.8 ms
    next-intlstatic14.7 KB153.6 KB4.2%89.8%21.8 KB16.0 ms14.7 ms
    next-intldynamic14.7 KB153.6 KB9.7%89.9%21.8 KB15.6 ms14.8 ms
    next-intlscoped-static14.7 KB153.6 KB0.0%0.0%80.1 KB17.9 ms17.4 ms
    next-intlscoped-dynamic14.7 KB153.6 KB0.0%0.0%22.9 KB17.8 ms16.8 ms
    @intlayer/next-intlstatic8.0 KB147.5 KB0.0%0.0%8.1 KB14.5 ms12.8 ms
    @intlayer/next-intldynamic8.0 KB148.7 KB0.0%0.0%8.1 KB11.7 ms12.8 ms
    next-intlayer (native)static5.5 KB141.3 KB0.0%0.0%8.5 KB15.5 ms16.9 ms
    next-intlayer (native)dynamic5.5 KB141.3 KB0.0%0.0%6.9 KB15.3 ms15.9 ms

    読み方

    • 同じコンポーネント、ページあたり 6 KB 削減。 アダプター ビルドのナイーブなアプリは 147.5 KB に到達し、完全に最適化されたもの (153.6 KB) を含む すべての next-intl 構成の下にあります。ランタイム自体が違い:8.0 KB 対 14.7 KB で、すべてのページで支払われます。
    • リークは何も変更することなく 0% に到達します。 ナイーブな next-intl セットアップは、すべてのページで外国ページ文字列の約 90% を配信しています。next-intl で 0% に到達するには、scoped-* セットアップが必要です:ルートごとに 1 つの namespace、および各ページで pick(messages, [...]) を使用します。アダプターは、optimize パスが各 useTranslations("ns") をそれ独自の辞書にバインドするため、ナイーブなコードから 0% に到達します。
    • コンポーネントは 2.7 倍縮小されます。 分離されたコンパイルされたコンポーネントは、next-intl の場合は平均 21.8 KB(プロバイダーとメッセージツリーに達します)で、アダプターの場合は 8.1 KB です。next-intl の scoped-static セットアップでは、その数は 80 KB に上がります。なぜなら、すべてのルートの namespace ファイルがそれを選択するページから到達可能になるからです。
    • Hydrationが2ms高速 (12.8 vs 14.7 ms): RSCペイロードから逆シリアル化するメッセージオブジェクトがないため、Reactが水和できます。
    • アダプターはネイティブランタイムではありません。 next-intlayerは141.3 KBで、ベースアプリの上に+0.3 KBで、5.5 KBのランタイムを備えています。アダプターはIntlayerのコア上にnext-intl APIサーフェス(useFormatter、t.rich、ICUリゾルバ)を搭載しており、したがって8.0 KBと1ページあたり+6 KBです。これはブリッジであり、目的地ではありません。
    すべてのライブラリと戦略の完全な表は、Next.js ベンチマークレポートをご覧ください。

    TanStack Start上の結果 (use-intl)

    use-intlはnext-intlのフレームワークに依存しないコアです。そのアダプター@intlayer/use-intlは、Viteプラグイン(@intlayer/use-intl/plugin)を使用して同じ設計に従います。

    セットアップストラテジーLib サイズ (gz)ページ JS 平均 (gz)ロケール漏洩ページ漏洩コンポーネント平均 (gz)E2E レスポンシビティハイドレーション
    base (i18n なし)-0.0 KB111.0 KB0.0%0.0%0.7 KB8.1 ms21.6 ms
    use-intlstatic14.1 KB179.8 KB50.0%89.8%76.0 KB6.7 ms15.3 ms
    use-intldynamic14.1 KB119.4 KB0.0%89.8%75.9 KB7.0 ms15.4 ms
    use-intlscoped-static14.1 KB128.7 KB0.0%0.0%87.1 KB20.9 ms24.8 ms
    use-intlscoped-dynamic14.1 KB128.7 KB0.0%0.0%87.1 KB13.3 ms25.9 ms
    @intlayer/use-intlstatic7.3 KB135.8 KB49.7%0.0%10.9 KB4.2 ms10.5 ms
    @intlayer/use-intldynamic7.3 KB129.7 KB0.0%0.0%9.3 KB8.7 ms16.1 ms
    intlayer (native)static5.0 KB125.8 KB50.0%0.0%8.1 KB3.2 ms11.5 ms
    intlayer (native)dynamic5.0 KB118.6 KB0.0%0.0%6.3 KB3.6 ms14.1 ms

    読み方

    • ページあたりのバイト数は最適化された use-intl と同等です。 @intlayer/use-intl の dynamic モード (129.7 KB) は use-intl の scoped-dynamic (128.7 KB) と 1 KB の差以内であり、use-intl の通常の dynamic (119.4 KB) より 10 KB 上回っています。その通常の dynamic 行は外部ページの文字列の 90% を依然リークしています。バイト数が低いのはテストアプリのコンテンツが小さいためです。アダプターの 0% はコンテンツが増加しても一定に保たれるものです。
    • コンポーネントは7~9倍小さい。 use-intlコンポーネントは平均76~87 KBでこれはすべての戦略で同じです。これはuseTranslationsがプロバイダーの全メッセージオブジェクトにバインドされているためです。アダプターは平均9~11 KBです。
    • ロケール切り替えが高速。 最適化されたuse-intlセットアップはhtml[lang]を更新するのに13~21 msかかります。アダプターは4~9 msかかります。再レンダリングされるコンポーネントが少なく、メッセージツリーから再取得されるものがありません。
    • staticはすべてのロケールを保持する。 アダプターのstatic行は49.7%のロケールリークを示しており、これはネイティブIntlayerのstaticモードと同じです。すべてのロケールがバンドルされ、ページの辞書のみが対象です。1行の設定(importMode: 'dynamic')でこれを削除できます。
    完全な表は、TanStack Start ベンチマークレポートをご覧ください。

    数字が変わる理由

    The Intlayer compiler extracts content from components

    コンポーネント内では何も変更されていないため、利益はすべてuseTranslationsがバインドされているもの由来です。

    next-intlの場合、バインディングはプロバイダーです。NextIntlClientProviderはロケールのmessagesオブジェクト全体を受け取り、すべてのuseTranslations("about")がそこから読み込まれます。バンドラーは1つのコンポーネントが1つのフックをインポートしており、そのフックが1つのコンテキストを読み込んでいることを認識しますが、aboutブランチのみが使用されていることを知ることはできません。以下のルートはすべて同じメッセージオブジェクトを共有しているため、page-leakカラムは自分でファイルを分割するまで〜90%を読み込みます, そして無駄なオーバーヘッドは、ページとロケールの両軸で同時に増大します:

    Theoretical content leakage by architecture

    bash
    .
    ├── messages
    │   ├── en.json                       # あらゆるnamespace、あらゆるpage
    │   └── fr.json
    └── src
        ├── i18n.ts                       # getRequestConfig({ messages: await import(...) })
        ├── middleware.ts                 # createMiddleware(routing)
        └── app/[locale]
            ├── layout.tsx                # <NextIntlClientProvider messages={messages}>
            └── about/page.tsx            # useTranslations("about")
    

    @intlayer/next-intlを使用する場合、バインディングは辞書です。syncJSONはmessages/en.jsonを1つのトップレベルキーごとに1つの辞書に変換します。コンパイラはuseTranslations("about")を呼び出すコンポーネントを解決し、アクティブなロケールでaboutを直接渡します。これはbundlerが追跡して分割できるimportです。

    bash
    .
    ├── intlayer.config.ts                # syncJSON({ source: ({ locale }) => `./messages/${locale}.json` })
    ├── messages
    │   ├── en.json                       # 変更なし、真実のソースのまま
    │   └── fr.json
    ├── .intlayer/                        # 生成: 名前空間とロケールごとに1つの辞書
    └── src
        ├── middleware.ts                 # createMiddleware() は現在 Intlayer のプロキシを返します
        └── app/[locale]
            ├── layout.tsx                # <NextIntlClientProvider> (messages prop なし)
            └── about/page.tsx            # useTranslations("about")  ← 変更なし
    

    src/i18n.ts と messages prop は廃止されます。その他はすべて同じです。

    3 つのステップでの移行

    1. インストール

      bash
      npx intlayer init --interactive
      

      このコマンドはnext-intlを検出し、intlayer、next-intlayer、@intlayer/next-intl、@intlayer/sync-json-pluginをインストールします。next-intlをインストール状態のままにしてください。これはアダプターのピア依存関係であり、型を提供しています。

    2. Intlayerをメッセージに指す

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      import { syncJSON } from "@intlayer/sync-json-plugin";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
          defaultLocale: Locales.ENGLISH,
        },
        dictionary: {
          // "static"はすべてのロケールをバンドルします。"dynamic"はオンデマンドでアクティブなものをロードします
          importMode: "dynamic",
        },
        plugins: [
          syncJSON({
            // ICUプレースホルダー: {name}, {count, plural, one {# item} other {# items}}
            format: "icu",
            source: ({ locale }) => `./messages/${locale}.json`,
            location: "messages",
          }),
        ],
      };
      
      export default config;
      

      messages/{locale}.json はそのままの場所に留まります。各トップレベルのキーは辞書になります。useTranslations("about") は about 辞書にマッピングされます。

    3. next.config.ts をラップする

      next.config.ts
      import type { NextConfig } from "next";
      import { createNextIntlPlugin } from "@intlayer/next-intl/plugin";
      
      const withIntlayer = createNextIntlPlugin();
      
      const nextConfig: NextConfig = {};
      
      export default withIntlayer(nextConfig);
      

      createNextIntlPlugin() は withIntlayer (コンテンツ監視、辞書コンパイル、最適化パス) と Webpack および Turbopack の next-intl → @intlayer/next-intl エイリアスを構成します。ビルドすれば、上記の表の数字があなたのものになります。

    その後削除できるもの

    ファイル / パターン理由
    src/i18n.ts の getRequestConfigリクエストごとのメッセージ読み込みがありません。ファイルは createNavigation ヘルパーもエクスポートする場合のみ保持してください
    messages={...} on NextIntlClientProviderアダプターはコンパイル済み出力を読み込みます。このプロップは無視され、開発時に警告がログに記録されます
    await getMessages() in layouts同じ理由
    Per-page pick(messages, [...])コンパイラーがコンポーネントごとにピッキングを実行します

    バイト数以上に得られるもの

    • 型付きキー。 useTranslations("about") はコンパイル済み about 辞書に対して型チェックされます。t("does.not.exist") はランタイムのフォールバックではなく TypeScript エラーになります。
    • npx intlayer test はロケールにキーが不足している場合にCIを失敗させます。npx intlayer fill は、選択したプロバイダー(OpenAI、Anthropic、Mistral、Gemini など)を使用して不足しているキーを翻訳し、独自のキーを使用して結果を messages/{locale}.json に書き込みます。
    • Visual Editor と CMS は同じ辞書を操作するため、開発者以外のユーザーは UI を通じて messages/fr.json を編集でき、ファイルが更新されます。
    • .content.ts への段階的な移行。 どのコンポーネントでも、useTranslations("about") から useIntlayer("about") へ、コンポーネントの近くにあるコンテンツファイルとともに、一度に 1 つずつ切り替えることができます。JSON と .content.ts の辞書は共存してマージされます。

    開始する前に知っておくべき制限事項

    createNavigation(routing) と createMiddleware(routing) は関数のシグネチャを維持しますが引数は無視されます。ロケール、デフォルトロケール、プレフィックス戦略は Intlayer の routing 設定から取得されます。next-intl のローカライズされた pathnames(/about から /a-propos)を使用している場合、アダプターはそれらを補間しません。Intlayer の routing.rewrite がそのケースをカバーしますが、これは別の設定変更となります。

    最適化パスは、インポートする辞書を特定するために静的な名前空間を必要とします。名前空間なしの呼び出しは、すべての辞書を参照するランタイムレジストリを介して引き続き動作しますが、これはまさに排除しようとしていたリークそのものです。名前空間を渡してください。

    next-intlayer の 5.5 KB に対して 8.0 KB のランタイムが必要であり、ネイティブビルドと比較してページあたり +6-7 KB 増加します。これは next-intl API サーフェスを維持するための代償です。すべてのコンポーネントが useIntlayer に移行したら、アダプターを削除してください。

    フォーマッターはネイティブの Intl に基づいており、ロケールのみが出力に影響します。ハイドレーションが安定した日付のために強制的なタイムゾーンや固定の now に依存している場合は、呼び出し側で処理してください。日付、時刻、数値のフォーマットを参照してください。

    どれを使うべきか?

    アプリが小さく、バンドルサイズが懸念事項ではなく、チームがページごとに名前空間と pick() を手動管理することに慣れている場合。

    現在すでに next-intl を使用しており、コードを書き直すことなくバンドル削減、リーク防止、ハイドレーションの高速化、型付けされたキー、CLI / CMS ツールを活用したい場合。これは既存の next-intl コードベースにとって推奨されるエントリポイントです。

    新規プロジェクト、またはアダプターがその役割を果たした後に適しています。3つの中で最も軽量であり(5.5 KB、ページあたり +0.3 KB)、同期サーバーコンポーネント、コンポーネントごとの .content.ts ファイル、およびすべてのフル機能を活用できます。Next.js での Intlayer の導入から始めてください。

    FAQ

    Next.js において、コンポーネントは変更不要です。ベンチマークのビルドでは next.config.ts と intlayer.config.ts のみを変更しました。src/i18n.ts 内の getRequestConfig、provider の messages プロパティ、およびページごとの pick() 呼び出しはデッドコードとなり、後から削除できます。

    そのまま動作し続けます。t("key", { count })、t.rich()、t.markup()、select、selectordinal、#、{ts, date, long} は Intlayer の ICU リゾルバーによって解決されます。ICU メッセージフォーマットを参照してください。

    Intlayer コアの上に next-intl API サーフェス(useFormatter、t.rich、ICU リゾルバー、ナビゲーションヘルパー)を搭載しているためです。これにより 5.5 KB に対して 8.0 KB となり、ページあたり +6 KB 増加します。これは架け橋であり、最終目的地ではありません。

    はい。任意のコンポーネントで、同一階層に .content.ts を配置することで useTranslations("about") から useIntlayer("about") へ移行できます。JSON と .content.ts の辞書は共存してマージされます。

    next-intl の pathnames 経由では機能しません。アダプターは型チェック用に受け入れますが補間は行いません。代わりに Intlayer の routing.rewrite を使用してください。

    関連する比較

    同じアダプターシリーズ:

    両ライブラリの直接比較:

    参考ドキュメント:

    これらのライブラリがどのように生まれたのかを知るには、JavaScript i18n の歴史をご覧ください。

    結論

    @intlayer/next-intl は 1 つのことを行います。useTranslations をバインドする対象を、すべてのメッセージを保持するプロバイダーから、そのコンポーネント用にコンパイルされた dictionary に変更します。1 ページあたり 6 KB の価値がある同じ Next.js アプリで、2.7 倍小さいコンポーネント、0% のリーケージ と 2 ms のハイドレーション が実現でき、誰もコンポーネント ファイルを開く前に達成されます。Navigation と middleware は Intlayer のルーティング設定の上で API を維持し、ネイティブ next-intlayer ランタイムはさらに軽いままです。

    すべてのraw data、テスト アプリ、およびスクリプトは Benchmark Bloom リポジトリ にあります。自分で実行してください。

    詳細については、'Why Intlayer?' ドキュメント を参照してください。

    コメント

    まだコメントはありません。最初のコメントを共有しましょう。

    関連記事

    最新の投稿