Автор:
    БозданиС:2024-03-07ПослСднСС обновлСниС:2026-08-30

    ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ вашСго сайта Π½Π° Vite ΠΈ React с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Intlayer | Π˜Π½Ρ‚Π΅Ρ€Π½Π°Ρ†ΠΈΠΎΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡ (i18n)

    Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅

    ΠŸΠΎΡ‡Π΅ΠΌΡƒ Intlayer Π»ΡƒΡ‡ΡˆΠ΅ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²?

    По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с основными Ρ€Π΅ΡˆΠ΅Π½ΠΈΡΠΌΠΈ, Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΊΠ°ΠΊ Β«react-i18nextΒ» ΠΈΠ»ΠΈ Β«i18nextΒ», Intlayer β€” это Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π² сСбя встроСнныС ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ:

    Intlayer ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ для идСальной Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Vite ΠΈ React, прСдлагая ΠΎΡ…Π²Π°Ρ‚ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‹ ΠΈ всС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π°Ρ†ΠΈΠΎΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ (i18n).

    ВмСсто Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΎΠ³Ρ€ΠΎΠΌΠ½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² JSON Π½Π° свои страницы Π·Π°Π³Ρ€ΡƒΠΆΠ°ΠΉΡ‚Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚. Intlayer ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±Π°Π½Π΄Π»Π° ΠΈ страниц Π΄ΠΎ 50Β %.

    ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ области содСрТимого вашСго прилоТСния ΠΎΠ±Π»Π΅Π³Ρ‡Π°Π΅Ρ‚ обслуТиваниС ΠΊΡ€ΡƒΠΏΠ½ΠΎΠΌΠ°ΡΡˆΡ‚Π°Π±Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π½Π΅ ΡƒΡ‚Ρ€ΡƒΠΆΠ΄Π°Π² сСбя мыслСнным Π±Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ всСй ΠΊΠΎΠ΄ΠΎΠ²ΠΎΠΉ Π±Π°Π·Ρ‹ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Intlayer ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½, Ρ‡Ρ‚ΠΎ обСспСчиваСт Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ вашСго ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.

    БовмСстноС Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ контСкст, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ для ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ большого языка (LLM). Intlayer Ρ‚Π°ΠΊΠΆΠ΅ поставляСтся с Π½Π°Π±ΠΎΡ€ΠΎΠΌ инструмСнтов, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ CLI для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ отсутствия ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠ²,LSP, MCP, ΠΈ agent skills, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° (DX) Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΉ для Π°Π³Π΅Π½Ρ‚ΠΎΠ² ИИ.

    Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ для ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° Π² своСм ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π΅ CI/CD, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ LLM ΠΏΠΎ Π²Π°ΡˆΠ΅ΠΌΡƒ Π²Ρ‹Π±ΠΎΡ€Ρƒ Π·Π° счСт вашСго поставщика ИИ. Intlayer Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ компилятор для Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ извлСчСния ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π²Π΅Π±-ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡƒ, которая ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π² Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅.

    ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² JSON ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ ΠΈ Ρ€Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒΡŽ. Intlayer ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° Π²ΠΎ врСмя сборки (build time).

    Intlayer β€” это большС, Ρ‡Π΅ΠΌ просто Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ i18n. Он прСдоставляСт Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½Ρ‹ΠΉ Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ ΠΈ ΠΏΠΎΠ»Π½Ρ‹ΠΉ CMS, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΌΠΎΡ‡ΡŒ Π²Π°ΠΌ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ многоязычным ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ΠΎΠΌ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, упрощая сотрудничСство с ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‡ΠΈΠΊΠ°ΠΌΠΈ, ΠΊΠΎΠΏΠΈΡ€Π°ΠΉΡ‚Π΅Ρ€Π°ΠΌΠΈ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ Ρ‡Π»Π΅Π½Π°ΠΌΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹. ΠšΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ локально ΠΈ/ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎ.

    ПошаговоС руководство ΠΏΠΎ настройкС Intlayer Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π½Π° Vite ΠΈ React

    youtube.com
    ide.intlayer.org
    intlayer-vite-react-template.vercel.app

    Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Application Template Π½Π° GitHub.

    1. Установка зависимостСй

      УстановитС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ npm:

      bash
      npx intlayer init --interactive
      
      Ρ„Π»Π°Π³ --interactive Π½Π΅ являСтся ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ intlayer-cli init, Ссли Π²Ρ‹ ΡΠ²Π»ΡΠ΅Ρ‚Π΅ΡΡŒ ИИ-Π°Π³Π΅Π½Ρ‚ΠΎΠΌ.
      Π­Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ Π²Π°ΡˆΡƒ срСду ΠΈ установит Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹. НапримСр:
      bash
      npm install intlayer react-intlayer
      npm install vite-intlayer --save-dev
      
      • intlayer Основной ΠΏΠ°ΠΊΠ΅Ρ‚, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ инструмСнты ΠΈΠ½Ρ‚Π΅Ρ€Π½Π°Ρ†ΠΈΠΎΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ для управлСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ, ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π°, объявлСния ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, транспиляции ΠΈ CLI-ΠΊΠΎΠΌΠ°Π½Π΄.

      • react-intlayer ΠŸΠ°ΠΊΠ΅Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Intlayer с ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π½Π° React. Он прСдоставляСт ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€Ρ‹ контСкста ΠΈ Ρ…ΡƒΠΊΠΈ для ΠΈΠ½Ρ‚Π΅Ρ€Π½Π°Ρ†ΠΈΠΎΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π² React.

      • vite-intlayer Π’ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΏΠ»Π°Π³ΠΈΠ½ Vite для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ Intlayer с сборщиком Vite, Π° Ρ‚Π°ΠΊΠΆΠ΅ middleware для опрСдСлСния ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, управлСния ΠΊΡƒΠΊΠΈ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ пСрСнаправлСния URL.

    2. ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

      АрхитСктура

      Π’ этой Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π΅ react-intlayer прСдоставляСт IntlayerProvider, смонтированный Π² main.tsx для оборачивания Π΄Π΅Ρ€Π΅Π²Π° React. ОбъявлСния ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ рядом с ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ Π² src/, Π° Vite ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ пСрСсборку ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΠΈ HMR с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ vite-intlayer.

      bash
      .
      β”œβ”€β”€ src
      β”‚   β”œβ”€β”€ app.content.tsx               # App content declaration
      β”‚   β”œβ”€β”€ App.css
      β”‚   β”œβ”€β”€ App.tsx                       # Main application component
      β”‚   β”œβ”€β”€ components
      β”‚   β”‚   β”œβ”€β”€ LocaleSwitcher.content.ts
      β”‚   β”‚   └── LocaleSwitcher.tsx
      β”‚   β”œβ”€β”€ index.css
      β”‚   β”œβ”€β”€ main.tsx                      # Entry point with IntlayerProvider
      β”‚   └── vite-env.d.ts
      β”œβ”€β”€ index.html
      β”œβ”€β”€ intlayer.config.ts
      β”œβ”€β”€ package.json
      β”œβ”€β”€ tsconfig.json
      └── vite.config.ts
      

      ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ

      Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ для настройки языков вашСго прилоТСния:

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [
            Locales.ENGLISH,
            Locales.FRENCH,
            Locales.SPANISH,
            // Π’Π°ΡˆΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π»ΠΎΠΊΠ°Π»ΠΈ
          ],
          defaultLocale: Locales.ENGLISH,
        },
      };
      
      export default config;
      
      Π§Π΅Ρ€Π΅Π· этот Ρ„Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ URL-адрСса, ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π² middleware, ΠΈΠΌΠ΅Π½Π° cookie, располоТСниС ΠΈ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Π²Π°ΡˆΠΈΡ… Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ†ΠΈΠΉ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π»ΠΎΠ³ΠΈ Intlayer Π² консоли ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ΅. Для ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ списка доступных ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ.
    3. Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ Intlayer Π² Π²Π°ΡˆΡƒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Vite

      Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠΏΠ»Π°Π³ΠΈΠ½ intlayer Π² Π²Π°ΡˆΡƒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ.

      vite.config.ts
      import { defineConfig } from "vite";
      import react from "@vitejs/plugin-react-swc";
      import { intlayer } from "vite-intlayer";
      
      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [react(), intlayer()],
      });
      
      Плагин Vite intlayer() ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ Intlayer с Vite. Он обСспСчиваСт созданиС Ρ„Π°ΠΉΠ»ΠΎΠ² Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ†ΠΈΠΉ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΠΈ отслСТиваСт ΠΈΡ… Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. Он опрСдСляСт ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния Intlayer Π²Π½ΡƒΡ‚Ρ€ΠΈ прилоТСния Vite. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΎΠ½ прСдоставляСт алиасы для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.
    4. ΠžΠ±ΡŠΡΠ²ΠΈΡ‚Π΅ Π’Π°Ρˆ ΠšΠΎΠ½Ρ‚Π΅Π½Ρ‚

      Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΈ управляйтС дСкларациями ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° для хранСния ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠ²:

      src/app.content.tsx
      import { t, type Dictionary } from "intlayer";
      import type { ReactNode } from "react";
      
      const appContent = {
        key: "app",
        content: {
          viteLogo: t({
            en: "Vite logo",
            fr: "Logo Vite",
            es: "Logo Vite",
          }),
          reactLogo: t({
            en: "React logo",
            fr: "Logo React",
            es: "Logo React",
          }),
      
          title: "Vite + React",
      
          count: t({
            en: "count is ",
            fr: "le compte est ",
            es: "el recuento es ",
          }),
      
          edit: t<ReactNode>({
            en: (
              <>
                Π Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ <code>src/App.tsx</code> ΠΈ сохранитС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ HMR
              </>
            ),
            fr: (
              <>
                Γ‰ditez <code>src/App.tsx</code> et enregistrez pour tester HMR
              </>
            ),
            es: (
              <>
                Edita <code>src/App.tsx</code> y guarda para probar HMR
              </>
            ),
          }),
      
          readTheDocs: t({
            en: "НаТмитС Π½Π° Π»ΠΎΠ³ΠΎΡ‚ΠΈΠΏΡ‹ Vite ΠΈ React, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ большС",
            fr: "Cliquez sur les logos Vite et React pour en savoir plus",
            es: "Haga clic en los logotipos de Vite y React para obtener mΓ‘s informaciΓ³n",
          }),
        },
      } соотвСтствуСт Dictionary;
      
      export default appContent;
      
      Π’Π°ΡˆΠΈ объявлСния ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² любом мСстС вашСго прилоТСния, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ½ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ contentDir (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, ./src). И ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡŽ Ρ„Π°ΠΉΠ»Π° объявлСния ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Для получСния Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΠΎ объявлСнию ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.
      Если ваш Ρ„Π°ΠΉΠ» ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΊΠΎΠ΄ TSX, рСкомСндуСтся ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ import React from "react"; Π² вашСм Ρ„Π°ΠΉΠ»Π΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.
    5. ИспользованиС Intlayer в вашСм кодС

      ΠŸΠΎΠ»ΡƒΡ‡Π°ΠΉΡ‚Π΅ доступ ΠΊ вашим словарям ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΠΏΠΎ всСму ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ:

      src/App.tsx
      import { useState, type FC } from "react";
      import reactLogo from "./assets/react.svg";
      import viteLogo from "/vite.svg";
      import "./App.css";
      import { IntlayerProvider, useIntlayer } from "react-intlayer";
      
      const AppContent: FC = () => {
        const [count, setCount] = useState(0);
        const content = useIntlayer("app");
      
        return (
          <>
            <div>
              <a href="https://vitejs.dev" target="_blank">
                <img src={viteLogo} className="logo" alt={content.viteLogo.value} />
              </a>
              <a href="https://react.dev" target="_blank">
                <img
                  src={reactLogo}
                  className="logo react"
                  alt={content.reactLogo.value}
                />
              </a>
            </div>
            <h1>{content.title}</h1>
            <div className="card">
              <button onClick={() => setCount((count) => count + 1)}>
                {content.count}
                {count}
              </button>
              <p>{content.edit}</p>
            </div>
            <p className="read-the-docs">{content.readTheDocs}</p>
          </>
        );
      };
      
      const App: FC = () => (
        <IntlayerProvider>
          <AppContent />
        </IntlayerProvider>
      );
      
      export default App;
      
      Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ваш ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π΅ Ρ‚ΠΈΠΏΠ° string, Ρ‚Π°ΠΊΠΎΠΌ ΠΊΠ°ΠΊ alt, title, href, aria-label ΠΈ Ρ‚.Π΄., Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:
      tsx
      <img src={content.image.src.value} alt={content.image.value} />
      <img src={content.image.src.toString()} alt={content.image.toString()} />
      <img src={String(content.image.src)} alt={String(content.image)} />
      

      Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ большС ΠΎ Ρ…ΡƒΠΊΠ΅ useIntlayer, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.

      Если вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡƒΠΆΠ΅ сущСствуСт, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Intlayer Compiler Π² сочСтании с ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ extract, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ тысячи ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² Π·Π° ΠΎΠ΄Π½Ρƒ сСкунду.
    6. ИзмСнСниС языка вашСго ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°

      ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ

      Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ язык вашСго ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ setLocale, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅ΠΌΡƒΡŽ Ρ…ΡƒΠΊΠΎΠΌ useLocale. Π­Ρ‚Π° функция позволяСт ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ локаль прилоТСния ΠΈ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ соотвСтствСнно.

      src/components/LocaleSwitcher.tsx
      import type { FC } from "react";
      import { Locales } from "intlayer";
      import { useLocale } from "react-intlayer";
      
      const LocaleSwitcher: FC = () => {
        const { setLocale } = useLocale();
      
        return (
          <button onClick={() => setLocale(Locales.English)}>
            Change Language to English
          </button>
        );
      };
      
      Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ большС ΠΎ Ρ…ΡƒΠΊΠ΅ useLocale, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.
    7. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ Π² вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅

      ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ

      ЦСль этого шага, ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ языка. Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для SEO ΠΈ SEO-друТСствСнных URL. ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

      plaintext
      - https://example.com/about
      - https://example.com/es/about
      - https://example.com/fr/about
      
      По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ прСфикса для Π»ΠΎΠΊΠ°Π»ΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ прСфикс для Π»ΠΎΠΊΠ°Π»ΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΎΠΏΡ†ΠΈΡŽ middleware.prefixDefault Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ true Π² вашСй ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ смотритС Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ.

      Π§Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ Π² вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ LocaleRouter, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ вашСго прилоТСния ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΡŽ Π½Π° основС Π»ΠΎΠΊΠ°Π»ΠΈ. Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с использованиСм React Router:

      src/components/LocaleRouter.tsx
      import { localeMap } from "intlayer"; // Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ ΠΈ Ρ‚ΠΈΠΏΡ‹ ΠΈΠ· 'intlayer'
      import type { FC, PropsWithChildren } from "react"; // Π’ΠΈΠΏΡ‹ React для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈ пропсов
      import { IntlayerProvider } from "react-intlayer"; // ΠŸΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€ для контСкста ΠΈΠ½Ρ‚Π΅Ρ€Π½Π°Ρ†ΠΈΠΎΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
      import { BrowserRouter, Route, Routes } from "react-router-dom"; // ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Ρ€ΠΎΡƒΡ‚Π΅Ρ€Π° для управлСния Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠ΅ΠΉ
      
      /**
       * ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ настраиваСт ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… Π»ΠΎΠΊΠ°Π»Π΅ΠΉ.
       * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ React Router для управлСния Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠ΅ΠΉ ΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².
       */
      export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
        <BrowserRouter>
          <Routes>
            {localeMap(({ locale, urlPrefix }) => (
              <Route
                // Π¨Π°Π±Π»ΠΎΠ½ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° для Π·Π°Ρ…Π²Π°Ρ‚Π° Π»ΠΎΠΊΠ°Π»ΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, /en/, /fr/) ΠΈ соотвСтствия всСм ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ путям
                path={`${urlPrefix}/*`}
                key={locale}
                element={
                  <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
                } // ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ элСмСнты с ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ локалью
              />
            ))}
          </Routes>
        </BrowserRouter>
      );
      
      ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: Ссли Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ routing.mode: 'no-prefix' | 'search-params', скорСС всСго, Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ localeMap.

      Π—Π°Ρ‚Π΅ΠΌ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ LocaleRouter Π² вашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ:

      src/App.tsx
      import { LocaleRouter } from "./components/LocaleRouter";
      import type { FC } from "react";
      
      // ... Π’Π°Ρˆ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ AppContent
      
      const App: FC = () => (
        <LocaleRouter>
          <AppContent />
        </LocaleRouter>
      );
      

      ΠŸΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ intlayerProxy для добавлСния ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π° сторонС сСрвСра Π² вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π­Ρ‚ΠΎΡ‚ ΠΏΠ»Π°Π³ΠΈΠ½ автоматичСски ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ локаль Π½Π° основС URL ΠΈ установит ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ cookie с локалью. Если локаль Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½Π°, ΠΏΠ»Π°Π³ΠΈΠ½ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ локаль Π½Π° основС языковых ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚Π΅Π½ΠΈΠΉ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Если локаль Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π°, ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° локаль ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

      ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ для использования intlayerProxy Π² ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚ vite-intlayer ΠΈΠ· devDependencies Π² dependencies.

      Начиная с Intlayer v9, intlayerProxy() встроСн Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Π² ΠΏΠ»Π°Π³ΠΈΠ½ intlayer() ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ‡Π΅Ρ€Π΅Π· ΠΎΠΏΡ†ΠΈΡŽ routing.enableProxy (true ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ). РСгистрация Π΅Π³ΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ являСтся Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ β€” ΠΎΠ½Π° сохранСна для ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ совмСстимости ΠΈ для ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ порядок ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ². УстановитС routing.enableProxy: false, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Π‘ΠΌ. примСчания ΠΊ Ρ€Π΅Π»ΠΈΠ·Ρƒ v9.
      vite.config.ts
      import { defineConfig } from "vite";
      import react from "@vitejs/plugin-react-swc";
      import { intlayer } from "vite-intlayer";
      
      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [
          react(),
          intlayer({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
        ],
      });
      
    8. ИзмСнСниС URL ΠΏΡ€ΠΈ смСнС Π»ΠΎΠΊΠ°Π»ΠΈ

      ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ

      Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ URL ΠΏΡ€ΠΈ смСнС Π»ΠΎΠΊΠ°Π»ΠΈ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠΏ onLocaleChange, прСдоставляСмый Ρ…ΡƒΠΊΠΎΠΌ useLocale. ΠŸΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ…ΡƒΠΊΠΈ useLocation ΠΈ useNavigate ΠΈΠ· react-router-dom для обновлСния ΠΏΡƒΡ‚ΠΈ URL.

      src/components/LocaleSwitcher.tsx
      import { useLocation, useNavigate } from "react-router-dom";
      import {
        Locales,
        getHTMLTextDir,
        getLocaleName,
        getLocalizedUrl,
      } from "intlayer";
      import { useLocale } from "react-intlayer";
      import { type FC } from "react";
      
      const LocaleSwitcher: FC = () => {
        const { pathname, search } = useLocation(); // ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΡƒΡ‚ΡŒ URL. ΠŸΡ€ΠΈΠΌΠ΅Ρ€: /fr/about?foo=bar
        const navigate = useNavigate();
      
        const { locale, availableLocales, setLocale } = useLocale({
          onLocaleChange: (locale) => {
            // Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ URL с ΠΎΠ±Π½ΠΎΠ²Π»Ρ‘Π½Π½ΠΎΠΉ локалью
            // ΠŸΡ€ΠΈΠΌΠ΅Ρ€: /es/about?foo=bar
            const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
      
            // ОбновляСм ΠΏΡƒΡ‚ΡŒ URL
            navigate(pathWithLocale);
          },
        });
      
        return (
          <div>
            <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
            <div id="localePopover" popover="auto">
              {availableLocales.map((localeItem) => (
                <a
                  href={getLocalizedUrl(location.pathname, localeItem)}
                  hrefLang={localeItem}
                  aria-current={locale === localeItem ? "page" : undefined}
                  onClick={(e) => {
                    e.preventDefault();
                    setLocale(localeItem);
                  }}
                  key={localeItem}
                >
                  <span>
                    {/* Π›ΠΎΠΊΠ°Π»ΡŒ - Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, FR */}
                    {localeItem}
                  </span>
                  <span>
                    {/* Π―Π·Ρ‹ΠΊ Π½Π° Π΅Π³ΠΎ собствСнной Π»ΠΎΠΊΠ°Π»ΠΈ - Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, FranΓ§ais */}
                    {getLocaleName(localeItem, locale)}
                  </span>
                  <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
                    {/* Π―Π·Ρ‹ΠΊ Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ - Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, FrancΓ©s ΠΏΡ€ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ Locales.SPANISH */}
                    {getLocaleName(localeItem)}
                  </span>
                  <span dir="ltr" lang={Locales.ENGLISH}>
                    {/* Π―Π·Ρ‹ΠΊ Π½Π° английском - Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, French */}
                    {getLocaleName(localeItem, Locales.ENGLISH)}
                  </span>
                </a>
              ))}
            </div>
          </div>
        );
      };
      

      Бсылки Π½Π° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ:

      НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½ ΠΎΠ±Π½ΠΎΠ²Π»Ρ‘Π½Π½Ρ‹ΠΉ Π¨Π°Π³ 9 с Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ объяснСниями ΠΈ ΡƒΡ‚ΠΎΡ‡Π½Ρ‘Π½Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΊΠΎΠ΄Π°:

    9. ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² языка ΠΈ направлСния Π² Ρ‚Π΅Π³Π΅ HTML

      ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ

      Когда вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ нСсколько языков, ΠΊΡ€Π°ΠΉΠ½Π΅ Π²Π°ΠΆΠ½ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ lang ΠΈ dir Ρ‚Π΅Π³Π° <html>, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ соотвСтствовали Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ. Π­Ρ‚ΠΎ обСспСчиваСт:

      • Π”ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ: ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ чтСния с экрана ΠΈ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ ΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π½Π° ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ lang для Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΈ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.
      • ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ тСкста: Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ dir (Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅) Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ тСкст отобраТаСтся Π² ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ порядкС (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ для английского, справа Π½Π°Π»Π΅Π²ΠΎ для арабского ΠΈΠ»ΠΈ ΠΈΠ²Ρ€ΠΈΡ‚Π°), Ρ‡Ρ‚ΠΎ Π²Π°ΠΆΠ½ΠΎ для удобочитаСмости.
      • SEO: поисковыС систСмы ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ lang для опрСдСлСния языка вашСй страницы, помогая ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°Ρ… поиска.

      Обновляя эти Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ динамичСски ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π»ΠΎΠΊΠ°Π»ΠΈ, Π²Ρ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΈ доступный ΠΎΠΏΡ‹Ρ‚ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° всСх ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… языках.

      РСализация Ρ…ΡƒΠΊΠ°

      Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Ρ…ΡƒΠΊ для управлСния Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ HTML. Π₯ΡƒΠΊ отслСТиваСт измСнСния Π»ΠΎΠΊΠ°Π»ΠΈ ΠΈ обновляСт Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

      src/hooks/useI18nHTMLAttributes.tsx
      import { useEffect } from "react";
      import { useLocale } from "react-intlayer";
      import { getHTMLTextDir } from "intlayer";
      
      /**
       * ΠžΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ `lang` ΠΈ `dir` элСмСнта <html> Π² зависимости ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ.
       * - `lang`: сообщаСт Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌ ΠΈ поисковым систСмам язык страницы.
       * - `dir`: обСспСчиваСт ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ порядок чтСния (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, 'ltr' для английского, 'rtl' для арабского).
       *
       * Π­Ρ‚ΠΎ динамичСскоС ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ для ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ отобраТСния тСкста, доступности ΠΈ SEO.
       */
      export const useI18nHTMLAttributes = () => {
        const { locale } = useLocale();
      
        useEffect(() => {
          // ΠžΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ языка Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ локаль.
          document.documentElement.lang = locale;
      
          // УстанавливаСт Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкста Π² зависимости ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ.
          document.documentElement.dir = getHTMLTextDir(locale);
        }, [locale]);
      };
      

      ИспользованиС Ρ…ΡƒΠΊΠ° Π² вашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ

      Π˜Π½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΡƒΠΉΡ‚Π΅ Ρ…ΡƒΠΊ Π² ваш Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ HTML обновлялись ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π»ΠΎΠΊΠ°Π»ΠΈ:

      src/App.tsx
      import type { FC } from "react";
      import { IntlayerProvider, useIntlayer } from "react-intlayer";
      import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
      import "./App.css";
      
      const AppContent: FC = () => {
        // ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ Ρ…ΡƒΠΊ для обновлСния Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² lang ΠΈ dir Ρ‚Π΅Π³Π° <html> Π² зависимости ΠΎΡ‚ Π»ΠΎΠΊΠ°Π»ΠΈ.
        useI18nHTMLAttributes();
      
        // ... ΠžΡΡ‚Π°Π»ΡŒΠ½Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ вашСго ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°
      };
      
      const App: FC = () => (
        <IntlayerProvider>
          <AppContent />
        </IntlayerProvider>
      );
      
      export default App;
      

      ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΡ эти измСнСния, вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚:

      • ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π΅ language (lang), Ρ‡Ρ‚ΠΎ Π²Π°ΠΆΠ½ΠΎ для SEO ΠΈ повСдСния Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°.
      • ΠΠ°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ тСкста (dir) Π² соотвСтствии с локалью, ΡƒΠ»ΡƒΡ‡ΡˆΠ°Ρ Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΡΡ‚ΡŒ ΠΈ удобство использования для языков с Ρ€Π°Π·Π½Ρ‹ΠΌ порядком чтСния.
      • ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ доступный ΠΎΠΏΡ‹Ρ‚, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ зависят ΠΎΡ‚ этих Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² для ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹.
    10. ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ

      Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ вашСго прилоТСния с ΡƒΡ‡Ρ‘Ρ‚ΠΎΠΌ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Link. Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ автоматичСски добавляСт прСфикс Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ языка ΠΊ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΌ URL, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠ³Π΄Π° франкоязычный ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ Π½Π° ссылку Π½Π° страницу "О нас", Π΅Π³ΠΎ пСрСнаправляСт Π½Π° /fr/about вмСсто /about.

      Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΏΠΎ нСскольким ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ:

      • SEO ΠΈ удобство для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ: Π›ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ URL ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ поисковым систСмам ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈΠ½Π΄Π΅ΠΊΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ страницы Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ языкС ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π½Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠΌ языкС.
      • ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ: Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡƒΡŽ ссылку ΠΏΠΎ всСму ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ, Π²Ρ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ навигация остаётся Π² Ρ€Π°ΠΌΠΊΠ°Ρ… Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ, прСдотвращая Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ языка.
      • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΠΎΡΡ‚ΡŒ: ЦСнтрализация Π»ΠΎΠ³ΠΈΠΊΠΈ Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ URL-адрСсами, дСлая ваш ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΈ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ роста прилоТСния.

      НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° рСализация Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Link Π½Π° TypeScript:

      src/components/Link.tsx
      import { getLocalizedUrl } from "intlayer";
      import {
        forwardRef,
        type DetailedHTMLProps,
        type AnchorHTMLAttributes,
      } from "react";
      import { useLocale } from "react-intlayer";
      
      export interface LinkProps extends DetailedHTMLProps<
        AnchorHTMLAttributes<HTMLAnchorElement>,
        HTMLAnchorElement
      > {}
      
      /**
       * Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ функция для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, являСтся Π»ΠΈ Π΄Π°Π½Π½Ρ‹ΠΉ URL внСшним.
       * Если URL начинаСтся с http:// ΠΈΠ»ΠΈ https://, ΠΎΠ½ считаСтся внСшним.
       */
      export const checkIsExternalLink = (href?: string): boolean =>
        /^https?:\/\//.test(href ?? "");
      
      /**
       * ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Link, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ href Π² зависимости ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ.
       * Для Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… ссылок ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ `getLocalizedUrl`, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ прСфикс Π»ΠΎΠΊΠ°Π»ΠΈ ΠΊ URL (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, /fr/about).
       * Π­Ρ‚ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ навигация останСтся Π² контСкстС Ρ‚ΠΎΠΉ ΠΆΠ΅ Π»ΠΎΠΊΠ°Π»ΠΈ.
       */
      export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
        ({ href, children, ...props }, ref) => {
          const { locale } = useLocale();
          const isExternalLink = checkIsExternalLink(href);
      
          // Если ссылка внутрСнняя ΠΈ href Π²Π°Π»ΠΈΠ΄Π΅Π½, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ URL.
          const hrefI18n =
            href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
      
          return (
            <a href={hrefI18n} ref={ref} {...props}>
              {children}
            </a>
          );
        }
      );
      
      Link.displayName = "Link";
      

      Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

      • ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π²Π½Π΅ΡˆΠ½ΠΈΡ… ссылок:
        Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ функция checkIsExternalLink опрСдСляСт, являСтся Π»ΠΈ URL внСшним. Π’Π½Π΅ΡˆΠ½ΠΈΠ΅ ссылки ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΠΌ Π½Π΅ трСбуСтся локализация.

      • ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π»ΠΎΠΊΠ°Π»ΠΈ:
        Π₯ΡƒΠΊ useLocale прСдоставляСт Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ локаль (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, fr для французского).

      • Локализация URL:
        Для Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… ссылок (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π½Π΅ Π²Π½Π΅ΡˆΠ½ΠΈΡ…) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ getLocalizedUrl, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ автоматичСски добавляСт прСфикс Π»ΠΎΠΊΠ°Π»ΠΈ ΠΊ URL. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ссли ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ французский язык, ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° /about Π² качСствС href прСобразуСтся Π² /fr/about.

      • Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ ссылки:
        ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ элСмСнт <a> с Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ URL, обСспСчивая ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΡƒΡŽ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ Π² соотвСтствии с Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΉ локалью.

      Π˜Π½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΡƒΡ этот ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Link ΠΏΠΎ всСму Π²Π°ΡˆΠ΅ΠΌΡƒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ, Π²Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΈ ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π½Π° язык ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΎΠΏΡ‹Ρ‚, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚Π΅ прСимущСства ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½Π½ΠΎΠ³ΠΎ SEO ΠΈ удобства использования.

    11. Π˜Π·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ содСрТимого Π²Π°ΡˆΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²

      ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ

      Если Ρƒ вас Π΅ΡΡ‚ΡŒ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ кодовая Π±Π°Π·Π°, ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ тысяч Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΡΡ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

      Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ этот процСсс, Intlayer ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ компилятор / экстрактор для прСобразования Π²Π°ΡˆΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈ извлСчСния содСрТимого.

      Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΅Π³ΠΎ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π» compiler Π² ваш Ρ„Π°ΠΉΠ» intlayer.config.ts:

      intlayer.config.ts
      import { type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        // ... ΠžΡΡ‚Π°Π»ΡŒΠ½Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ вашСй ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
        compiler: {
          /**
           * Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π»ΠΈ Π±Ρ‹Ρ‚ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ компилятор.
           */
          enabled: true,
      
          /**
           * ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ ΠΏΡƒΡ‚ΡŒ ΠΊ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»Π°ΠΌ
           */
          output: ({ fileName, extension }) => `./${fileName}${extension}`,
      
          /**
           * Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒΡΡ послС прСобразования. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, компилятор ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· для прСобразования прилоТСния, Π° Π·Π°Ρ‚Π΅ΠΌ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ.
           */
          saveComponents: false,
      
          /**
           * ΠŸΡ€Π΅Ρ„ΠΈΠΊΡ ΠΊΠ»ΡŽΡ‡Π° словаря
           */
          dictionaryKeyPrefix: "",
        },
      };
      
      export default config;
      

      ЗапуститС экстрактор для прСобразования ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈ извлСчСния содСрТимого

      bash
      npx intlayer extract
      
      Since v9, the intlayerCompiler is included in the intlayer plugin. So you don't need to add it manually.

      ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚Π΅ ваш vite.config.ts, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΠ»Π°Π³ΠΈΠ½ intlayerCompiler:

      vite.config.ts
      import { defineConfig } from "vite";
      import { intlayer, intlayerCompiler } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [
          intlayer(),
          intlayerCompiler(), // Adds the compiler plugin
        ],
      });
      
      bash
      npm run build # Или npm run dev
      

    (ΠžΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ) Sitemap ΠΈ robots.txt (гСнСрация Π½Π° сборкС)

    Intlayer прСдоставляСт generateSitemap ΠΈ getMultilingualUrls - ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‚ многоязычныС sitemap.xml ΠΈ robots.txt для ΠΊΡ€Π°ΡƒΠ»Π΅Ρ€ΠΎΠ² ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ автоматичСски Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΡ… Π² public/. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ нСбольшой Node-скрипт Π΄ΠΎ Vite (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, npm-Ρ…ΡƒΠΊΠΈ predev / prebuild).

    Sitemap

    Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ sitemap ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ Π»ΠΎΠΊΠ°Π»ΠΈ ΠΈ добавляСт Π½ΡƒΠΆΠ½Ρ‹Π΅ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅.

    ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ пространство ΠΈΠΌΡ‘Π½ xhtml:link (hreflang). ВмСсто плоского списка URL Intlayer связываСт всС языковыС вСрсии страницы Π² ΠΎΠ±Π΅ стороны (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ /about, /fr/about ΠΈΠ»ΠΈ /about?lang=fr Π² зависимости ΠΎΡ‚ Ρ€Π΅ΠΆΠΈΠΌΠ° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ).

    Robots.txt

    Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ getMultilingualUrls, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π°Π²ΠΈΠ»Π° Disallow ΠΏΠΎΠΊΡ€Ρ‹Π²Π°Π»ΠΈ всС Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΏΡƒΡ‚Π΅ΠΉ.

    1. Π€Π°ΠΉΠ» generate-seo.mjs Π² ΠΊΠΎΡ€Π½Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

    generate-seo.mjs
    import fs from "fs";
    import path from "path";
    import { fileURLToPath } from "url";
    import { generateSitemap, getMultilingualUrls } from "intlayer";
    
    const __dirname = path.dirname(fileURLToPath(import.meta.url));
    
    const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(
      /\/$/,
      ""
    );
    
    const pathList = [
      { path: "/", changefreq: "daily", priority: 1.0 },
      { path: "/about", changefreq: "monthly", priority: 0.7 },
    ];
    
    const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });
    fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);
    
    const getAllMultilingualUrls = (urls) =>
      urls.flatMap((url) => Object.values(getMultilingualUrls(url)));
    
    const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);
    
    const robotsTxt = [
      "User-agent: *",
      "Allow: /",
      ...disallowedPaths.map((path) => `Disallow: ${path}`),
      "",
      `Sitemap: ${SITE_URL}/sitemap.xml`,
    ].join("\n");
    
    fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);
    
    console.log("SEO files generated successfully.");
    

    ΠŸΠ°ΠΊΠ΅Ρ‚ intlayer Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ установлСн. Для ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π° Π·Π°Π΄Π°ΠΉΡ‚Π΅ SITE_URL Π² ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² CI).

    Для Node ESM ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ generate-seo.mjs. Для generate-seo.js ΡƒΠΊΠ°ΠΆΠΈΡ‚Π΅ "type": "module" Π² package.json ΠΈΠ»ΠΈ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ ESM ΠΈΠ½Π°Ρ‡Π΅.

    2. Запуск скрипта Π΄ΠΎ Vite

    package.json
    {
      "scripts": {
        "dev": "vite",
        "prebuild": "node generate-seo.mjs",
        "build": "vite build",
        "preview": "vite preview"
      }
    }
    

    ΠŸΠΎΠ΄ΡΡ‚Ρ€ΠΎΠΉΡ‚Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ для pnpm ΠΈΠ»ΠΈ yarn. Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΠ· CI ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ шага.

    Настройка TypeScript

    Intlayer ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ (module augmentation), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ прСимущСства TypeScript ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π²Π°ΡˆΡƒ codebase Π±ΠΎΠ»Π΅Π΅ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠΉ.

    АвтодополнСниС

    Ошибка ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π°

    Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ ваша конфигурация TypeScript Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ автоматичСски сгСнСрированныС Ρ‚ΠΈΠΏΡ‹.

    tsconfig.json
    {
      // ... Π’Π°ΡˆΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ TypeScript
      "include": [
        // ... Π’Π°ΡˆΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ TypeScript
        ".intlayer/**/*.ts", // Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ автоматичСски сгСнСрированныС Ρ‚ΠΈΠΏΡ‹
      ],
    }
    

    ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ Git

    РСкомСндуСтся ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ Intlayer. Π­Ρ‚ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΈΡ… ΠΊΠΎΠΌΠΌΠΈΡ‚Π° Π² ваш Git-Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ.

    Для этого Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ инструкции Π² ваш Ρ„Π°ΠΉΠ» .gitignore:

    .gitignore
    # Π˜Π³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ Intlayer
    .intlayer
    

    Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ VS Code

    Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ваш ΠΎΠΏΡ‹Ρ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ с Intlayer, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Intlayer VS Code Extension.

    Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΈΠ· VS Code Marketplace

    Π­Ρ‚ΠΎ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ прСдоставляСт:

    • АвтодополнСниС для ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π°.
    • ΠžΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ ошибок Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ для ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠ².
    • ВстроСнный прСдпросмотр ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.
    • БыстрыС дСйствия для Π»Π΅Π³ΠΊΠΎΠ³ΠΎ создания ΠΈ обновлСния ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠ².

    Для получСния Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Intlayer VS Code Extension.

    ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ возмоТности

    Для Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ возмоТностСй Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ ΠΈΠ»ΠΈ вынСсти ваш ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π²ΠΎ внСшний CMS.

    Часто Π·Π°Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ вопросы

    Π£ Vite Π½Π΅Ρ‚ мнСния ΠΎΠ± i18n, поэтому Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ - это Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ экосистСмы React:

    • react-i18next / i18next: самый распространённый, с пространствами ΠΈΠΌΡ‘Π½ JSON, Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹ΠΌΠΈ Π²ΠΎ врСмя выполнСния.
    • react-intl ΠΈ Lingui: Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ сообщСний ICU, Π½Π° основС извлСчСния.
    • Intlayer: ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚, ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΉ рядом с ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ, скомпилированный ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠΌ Vite Π²ΠΎ врСмя сборки, ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ, с ИИ-ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠΌ, Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ΠΎΠΌ ΠΈ CMS.

    ИмСнно Π² Vite Intlayer встраиваСтся Π² сборку, поэтому ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΡŽΡ‚ΡΡ ΠΈ ΠΏΠΎΠ΄Π²Π΅Ρ€Π³Π°ΡŽΡ‚ΡΡ tree-shaking Π²ΠΎ врСмя компиляции, Π° Π½Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ JSON Π²ΠΎ врСмя выполнСния. Π‘ΠΌ. ΠΏΠΎΡ‡Π΅ΠΌΡƒ Intlayer ΠΈ Π±Π΅Π½Ρ‡ΠΌΠ°Ρ€ΠΊ.

    Π“ΠΎΡ€Π°Π·Π΄ΠΎ мСньшС, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π΅ Π½Π° основС пространств ΠΈΠΌΡ‘Π½, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ страница Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ Π²ΠΎ врСмя сборки замСняСт Π²Ρ‹Π·ΠΎΠ²Ρ‹ useIntlayer Ρ‚ΠΎΡ‡Π½Ρ‹ΠΌΠΈ записями словаря, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, поэтому Π½Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΈ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ языки ΠΎΡ‚Π±Ρ€Π°ΡΡ‹Π²Π°ΡŽΡ‚ΡΡ, Π° динамичСскиС словари Ρ€Π°Π·Π΄Π΅Π»ΡΡŽΡ‚ ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎ локалям. По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌΠΈ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π°ΠΌΠΈ Intlayer сокращаСт Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±Π°Π½Π΄Π»Π° ΠΈ страницы Π΄ΠΎ 50%. Π‘ΠΌ. ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ Π±Π°Π½Π΄Π»Π° ΠΈ Π±Π΅Π½Ρ‡ΠΌΠ°Ρ€ΠΊ.

    Π”Π°, ΠΈ Π΅ΡΡ‚ΡŒ Π΄Π²Π° ΠΏΡƒΡ‚ΠΈ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΌΠΈΠ³Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ постСпСнно с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ руководства ΠΏΠΎ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ с react-i18next ΠΈΠ»ΠΈ руководства ΠΏΠΎ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ с i18next. Или Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ свой Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ API: Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ совмСстимости ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ API, ΠΊΠ°ΠΊ react-i18next, react-intl ΠΈ i18next, Π½ΠΎ обслуТиваСмый словарями Intlayer, поэтому ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ ΠΈΠΌΠΏΠΎΡ€Ρ‚Ρ‹, Π° ΠΊΠΎΠ΄ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² - Π½Π΅Ρ‚.

    Π”Π°. Плагин синхронизации JSON сохраняСт ваши Ρ„Π°ΠΉΠ»Ρ‹ /messages/{locale}/{namespace}.json ΠΊΠ°ΠΊ источник истины ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈΠ· Π½ΠΈΡ… словари Intlayer, Π² ΠΎΠ±ΠΎΠΈΡ… направлСниях. Плагин синхронизации PO Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅ самоС для ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ² gettext, Π° Ρ„Π°ΠΉΠ»Ρ‹ ΠΏΠΎ Π»ΠΎΠΊΠ°Π»ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΠΏΠΎ языкам вмСсто Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠΈ Π»ΠΎΠΊΠ°Π»Π΅ΠΉ Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅.

    НСт. ЗапуститС npx intlayer extract, ΠΈ Intlayer ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚ ваши ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, ΠΈΠ·Π²Π»Π΅Ρ‡Ρ‘Ρ‚ строки, Π²ΠΈΠ΄ΠΈΠΌΡ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ, ΠΈ Π·Π°ΠΏΠΈΡˆΠ΅Ρ‚ Ρ„Π°ΠΉΠ» .content рядом с ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ ΠΈΠ· Π½ΠΈΡ…, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²Ρ‹ просматриваСтС diff вмСсто копирования строк Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ. Π¨Π°Π³ 11 этого руководства ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ вас Ρ‡Π΅Ρ€Π΅Π· это.

    Для ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ Intlayer Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅ самоС Π²ΠΎ врСмя сборки: ΠΎΠ½ сканируСт исходный ΠΊΠΎΠ΄ JSX, TSX, Vue ΠΈ Svelte ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ словари ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΈΡ… ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ Ρ‡Π΅Ρ€Π΅Π· Π³ΠΎΡ€ΡΡ‡ΡƒΡŽ Π·Π°ΠΌΠ΅Π½Ρƒ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ, поэтому Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡ΠΈ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ.

    Π‘Ρ‚ΠΎΠΈΡ‚ Π·Π½Π°Ρ‚ΡŒ ΠΎ Π΄Π²ΡƒΡ… ограничСниях, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ компилятор. Он Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· статичСский Π°Π½Π°Π»ΠΈΠ·, поэтому строки, ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²ΠΎ врСмя выполнСния, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΊΠΎΠ΄Ρ‹ ошибок API ΠΈΠ»ΠΈ поля CMS, ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ нСдоступными. И Π΅ΠΌΡƒ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒ тСкст, Π²ΠΈΠ΄ΠΈΠΌΡ‹ΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ, ΠΎΡ‚ Π»ΠΎΠ³ΠΈΠΊΠΈ прилоТСния Π²Ρ€ΠΎΠ΄Π΅ className="active" ΠΈΠ»ΠΈ ΠΊΠΎΠ΄Π° статуса, Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ Π² большой ΠΊΠΎΠ΄ΠΎΠ²ΠΎΠΉ Π±Π°Π·Π΅. Команда extract ΠΈΠ·Π±Π΅Π³Π°Π΅Ρ‚ ΠΎΠ±ΠΎΠΈΡ… ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ, оставляя вас Π² процСссС.

    ΠŸΡΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², всС ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅:

    • Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ для VS Code: ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΎΡ‚ ΠΊΠ»ΡŽΡ‡Π° useIntlayer ΠΊ Ρ„Π°ΠΉΠ»Ρƒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΅Π³ΠΎ ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚, ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° ΠΈΠ· ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΈ запуск build, fill, test, push ΠΈ pull ΠΈΠ· ΠΏΠ°Π»ΠΈΡ‚Ρ€Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄ ΠΈΠ»ΠΈ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Intlayer.
    • LSP-сСрвСр: Ρ‚Π° ΠΆΠ΅ ΠΎΡΠ²Π΅Π΄ΠΎΠΌΠ»Ρ‘Π½Π½ΠΎΡΡ‚ΡŒ Π² любом Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ Π½Π° LSP, с ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΎΠΌ ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΡŽ, поиском всСх ссылок, прСдпросмотром ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ значСния ΠΏΡ€ΠΈ Π½Π°Π²Π΅Π΄Π΅Π½ΠΈΠΈ, Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΈ ΠΏΠΎΠ»Π΅ΠΉ ΠΈ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΊΠ»ΡŽΡ‡ Π½ΠΈΠ³Π΄Π΅ Π½Π΅ объявлСн. Он Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Π²Ρ‹Π·ΠΎΠ²Ρ‹ i18next, react-i18next, next-intl ΠΈ use-intl, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΡ€ΠΈ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ.
    • MCP-сСрвСр: прСдоставляСт Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ ΠΈ CLI Intlayer для Cursor, VS Code, Claude Desktop, Claude Code ΠΈ ChatGPT, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ассистСнт ΠΎΡ‚Π²Π΅Ρ‡Π°Π» ΠΏΠΎ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ, Π° Π½Π΅ Π³Π°Π΄Π°Π», ΠΈ ΠΌΠΎΠ³ сам Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π²Ρ€ΠΎΠ΄Π΅ intlayer fill.
    • Навыки Π°Π³Π΅Π½Ρ‚ΠΎΠ²: сфокусированныС Π½Π°Π²Ρ‹ΠΊΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ intlayer-config, intlayer-cli ΠΈ intlayer-content, плюс ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Π½Π° Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±ΡƒΡ‡Π°ΡŽΡ‚ Π°Π³Π΅Π½Ρ‚Π° вашСй настройкС ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ Ρ‚ΠΈΠΏΠ°ΠΌ ΡƒΠ·Π»ΠΎΠ² ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.
    • Плагин ESLint: no-raw-text ΠΏΠΎΠΌΠ΅Ρ‡Π°Π΅Ρ‚ Тёстко Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ строки, с Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌΠΈ для статичСских ΠΊΠ»ΡŽΡ‡Π΅ΠΉ словаря ΠΈ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.