Author:
    Creation:2025-09-09Last update:2026-09-27

    Intlayer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреА TanStack Start рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ

    рд╡рд┐рд╖рдп-рд╕реВрдЪреА

    рдпрд╣ рдЧрд╛рдЗрдб рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдХреЗрд▓-рдЬрд╛рдЧрд░реВрдХ рд░реВрдЯрд┐рдВрдЧ, TypeScript рд╕рдорд░реНрдерди рдФрд░ рдЖрдзреБрдирд┐рдХ рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдерд╛рдУрдВ рдХреЗ рд╕рд╛рде TanStack Start рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдореЗрдВ рдирд┐рд░реНрдмрд╛рдз рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рдХреЗ рд▓рд┐рдП Intlayer рдХреЛ рдХреИрд╕реЗ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдПред

    рд╡рд┐рдХрд▓реНрдкреЛрдВ рдкрд░ рдЗрдиреНрдЯрд▓реЗрдпрд░ рдХреНрдпреЛрдВ?

    react-i18next рдпрд╛ use-intl, рдпрд╛ paraglide рдЬреИрд╕реЗ рдореБрдЦреНрдп рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ, Intlayer рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рдПрдХреАрдХреГрдд рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИ рдЬреИрд╕реЗ:

    рдЗрдВрдЯрд▓реЗрдпрд░ рдЯреИрдирд╕реНрдЯреИрдХ рд╕реНрдЯрд╛рд░реНрдЯ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рд╣реИ, рдЬреЛ рдмрд╣реБрднрд╛рд╖реА рд░реВрдЯрд┐рдВрдЧ, рдХреБрдХреА рдкреНрд░рдмрдВрдзрди, рд╕рд╛рдЗрдЯрдореИрдк рдЬреЗрдирд░реЗрд╢рди, рдбрд╛рдпрдирд╛рдорд┐рдХ рдХрдВрдЯреЗрдВрдЯ рд▓реЛрдбрд┐рдВрдЧ рдФрд░ рдЖрдкрдХреЗ рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг (i18n) рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

    рдЕрдкрдиреЗ рдкреГрд╖реНрдареЛрдВ рдореЗрдВ рд╡рд┐рд╢рд╛рд▓ JSON рдлрд╝рд╛рдЗрд▓реЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рд╕рд╛рдордЧреНрд░реА рд▓реЛрдб рдХрд░реЗрдВред рдЗрдВрдЯрд▓реЗрдпрд░ рдЖрдкрдХреЗ рдмрдВрдбрд▓ рдФрд░ рдкреГрд╖реНрда рдЖрдХрд╛рд░ рдХреЛ 50% рддрдХ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред

    рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рд╕рд╛рдордЧреНрд░реА рдХрд╛ рджрд╛рдпрд░рд╛ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд░рдЦрд░рдЦрд╛рд╡ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЖрдк рдЕрдкрдиреЗ рд╕рдВрдкреВрд░реНрдг рд╕рд╛рдордЧреНрд░реА рдХреЛрдбрдмреЗрд╕ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рдорд╛рдирд╕рд┐рдХ рдмреЛрдЭ рдХреЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдПрдХ рдлреАрдЪрд░ рдлрд╝реЛрд▓реНрдбрд░ рдХреА рдирдХрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЙрд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЖрдкрдХреА рд╕рд╛рдордЧреНрд░реА рдХреА рд╕рдЯреАрдХрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Intlayer рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

    рд╕рд╛рдордЧреНрд░реА рдХрд╛ рд╕рд╣-рд╕реНрдерд╛рдиреАрдХрд░рдг рдмрдбрд╝реЗ рднрд╛рд╖рд╛ рдореЙрдбрд▓ (рдПрд▓рдПрд▓рдПрдо) рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХ рд╕рдВрджрд░реНрдн рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИред рдЗрдВрдЯрд▓реЗрдпрд░ рдЯреВрд▓ рдХреЗ рдПрдХ рд╕реВрдЯ рдХреЗ рд╕рд╛рде рднреА рдЖрддрд╛ рд╣реИ, рдЬреИрд╕реЗ CLI рддрд╛рдХрд┐ рд▓рд╛рдкрддрд╛ рдЕрдиреБрд╡рд╛рджреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ,LSP, MCP, рдФрд░ agent skills, AI рдПрдЬреЗрдВрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрд╡рд▓рдкрд░ рдЕрдиреБрднрд╡ (DX) рдХреЛ рдФрд░ рднреА рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдПред

    рдЕрдкрдиреЗ рдПрдЖрдИ рдкреНрд░рджрд╛рддрд╛ рдХреА рдХреАрдордд рдкрд░ рдЕрдкрдиреА рдкрд╕рдВрдж рдХреЗ рдПрд▓рдПрд▓рдПрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рд╕реАрдЖрдИ/рд╕реАрдбреА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рдЪрд╛рд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЗрдВрдЯрд▓реЗрдпрд░ рд╕рд╛рдордЧреНрд░реА рдирд┐рд╖реНрдХрд░реНрд╖рдг рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдкреГрд╖реНрдарднреВрдорд┐ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдореЗрдВ рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реЗрдм рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

    рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ JSON рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдШрдЯрдХреЛрдВ рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рд╕рдВрдмрдВрдзреА рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдЗрдВрдЯрд▓реЗрдпрд░ рдмрд┐рд▓реНрдб рд╕рдордп рдкрд░ рдЖрдкрдХреА рд╕рд╛рдордЧреНрд░реА рд▓реЛрдбрд┐рдВрдЧ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред

    рд╕рд┐рд░реНрдл рдПрдХ i18n рд╕рдорд╛рдзрд╛рди рд╕реЗ рдЕрдзрд┐рдХ, Intlayer рдПрдХ рд╕реНрд╡-рд╣реЛрд╕реНрдЯреЗрдб рд╡рд┐рдЬрд╝реБрдЕрд▓ рдПрдбрд┐рдЯрд░ рдФрд░ рдПрдХ рдкреВрд░реНрдг рд╕реАрдПрдордПрд╕ рдЖрдкрдХреА рдмрд╣реБрднрд╛рд╖реА рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЕрдиреБрд╡рд╛рджрдХреЛрдВ, рдХреЙрдкреАрд░рд╛рдЗрдЯрд░реЛрдВ рдФрд░ рдЯреАрдо рдХреЗ рдЕрдиреНрдп рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╣рдпреЛрдЧ рд╕рд╣рдЬ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕реНрдерд╛рдиреАрдп рдФрд░/рдпрд╛ рджреВрд░рд╕реНрде рд░реВрдк рд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

    TanStack Start рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ Intlayer рд╕реЗрдЯ рдЕрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░рдг-рджрд░-рдЪрд░рдг рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛

    youtube.com
    ide.intlayer.org
    intlayer-tanstack-start-template.vercel.app

    GitHub рдкрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЯреЗрдореНрдкрд▓реЗрдЯ рджреЗрдЦреЗрдВред

    1. рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ

      TanStack Start рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рдирдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╢реБрд░реВ рдХрд░реЗрдВ рдЧрд╛рдЗрдб рдХрд╛ рдкрд╛рд▓рди рдХрд░рдХреЗ рдПрдХ рдирдпрд╛ TanStack Start рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВред

    2. Intlayer рдкреИрдХреЗрдЬ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ

      рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ рдкреИрдХреЗрдЬ рдореИрдиреЗрдЬрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрд╡рд╢реНрдпрдХ рдкреИрдХреЗрдЬ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ:

      bash
      npx intlayer init --interactive
      
      --interactive рдзреНрд╡рдЬ (flag) рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХ AI рдПрдЬреЗрдВрдЯ рд╣реИрдВ рддреЛ intlayer-cli init рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
      рдпрд╣ рдХрдорд╛рдВрдб рдЖрдкрдХреЗ рдПрдирд╡рд╛рдпрд░рдирдореЗрдВрдЯ рдХреЛ рдбрд┐рдЯреЗрдХреНрдЯ рдХрд░реЗрдЧреА рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдкреИрдХреЗрдЬ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдЧреАред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
      bash
      npm install intlayer react-intlayer
      npm install vite-intlayer --save-dev
      
      • intlayer

        рдХреЛрд░ рдкреИрдХреЗрдЬ рдЬреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкреНрд░рдмрдВрдзрди, рдЕрдиреБрд╡рд╛рдж, рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛, рдЯреНрд░рд╛рдВрд╕рдкрд╛рдЗрд▓реЗрд╢рди рдФрд░ CLI рдХрдорд╛рдВрдб рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рдЙрдкрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

      • react-intlayer рд╡рд╣ рдкреИрдХреЗрдЬ рдЬреЛ Intlayer рдХреЛ React рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рддрд╛ рд╣реИред рдпрд╣ React рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рдХреЗ рд▓рд┐рдП рд╕рдВрджрд░реНрдн рдкреНрд░рджрд╛рддрд╛ рдФрд░ рд╣реБрдХ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

      • vite-intlayer рдЗрд╕рдореЗрдВ Intlayer рдХреЛ Vite рдмрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Vite рдкреНрд▓рдЧрдЗрди, рд╕рд╛рде рд╣реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдкрд╕рдВрджреАрджрд╛ рд▓реЛрдХреЗрд▓ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ, рдХреБрдХреАрдЬрд╝ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдФрд░ URL рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рдбрд▓рд╡реЗрдпрд░ рд╢рд╛рдорд┐рд▓ рд╣реИред

    3. рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди

      рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░

      рдЗрд╕ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдореЗрдВ, рд╕рднреА рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд░реВрдЯреНрд╕ {-$locale} рд░реВрдЯ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рддрд╣рдд рдиреЗрд╕реНрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рд╖рд╛ рдХрд╛ рдПрдХ рд╕рдорд░реНрдкрд┐рдд URL рд╣реЛ, рд╕рд╛рде рд╣реА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд▓реЛрдХреЗрд▓ рдкреНрд░реАрдлрд╝рд┐рдХреНрд╕, рд╕рддреНрдпрд╛рдкрди рдФрд░ SEO рдЕрдиреБрдХреВрд▓рди рд╕рдХреНрд╖рдо рдХрд░рддрд╛ рд╣реИред

      bash
      .
      тФЬтФАтФА src
      тФВ   тФЬтФАтФА components
      тФВ   тФВ   тФЬтФАтФА Header.tsx
      тФВ   тФВ   тФЬтФАтФА locale-switcher.content.ts
      тФВ   тФВ   тФЬтФАтФА locale-switcher.tsx
      тФВ   тФВ   тФФтФАтФА localized-link.tsx
      тФВ   тФЬтФАтФА hooks
      тФВ   тФВ   тФЬтФАтФА useI18nHTMLAttributes.tsx
      тФВ   тФВ   тФФтФАтФА useLocalizedNavigate.ts
      тФВ   тФЬтФАтФА routes
      тФВ   тФВ   тФЬтФАтФА {-$locale}
      тФВ   тФВ   тФВ   тФЬтФАтФА 404.content.ts
      тФВ   тФВ   тФВ   тФЬтФАтФА 404.tsx
      тФВ   тФВ   тФВ   тФЬтФАтФА about.content.ts
      тФВ   тФВ   тФВ   тФЬтФАтФА about.tsx
      тФВ   тФВ   тФВ   тФЬтФАтФА index.content.tsx
      тФВ   тФВ   тФВ   тФЬтФАтФА index.tsx
      тФВ   тФВ   тФВ   тФФтФАтФА route.tsx             # Locale layout & prefix validation
      тФВ   тФВ   тФЬтФАтФА __root.tsx                # Root route with IntlayerProvider
      тФВ   тФВ   тФФтФАтФА sitemap[.]xml.ts
      тФВ   тФЬтФАтФА router.tsx
      тФВ   тФФтФАтФА styles.css
      тФЬтФАтФА intlayer.config.ts
      тФЬтФАтФА package.json
      тФЬтФАтФА tsconfig.json
      тФФтФАтФА vite.config.ts
      

      рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди

      рдЕрдкрдиреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рднрд╛рд╖рд╛рдУрдВ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ:

      intlayer.config.ts
      import type { IntlayerConfig } from "intlayer";
      
      import { Locales } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          defaultLocale: Locales.ENGLISH,
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        },
      };
      
      export default config;
      
      рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЖрдк рд╕реНрдерд╛рдиреАрдпрдХреГрдд URL, рдорд┐рдбрд▓рд╡реЗрдпрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди, рдХреБрдХреА рдирд╛рдо, рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛рдУрдВ рдХрд╛ рд╕реНрдерд╛рди рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХрдВрд╕реЛрд▓ рдореЗрдВ Intlayer рд▓реЙрдЧ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдмрд╣реБрдд рдХреБрдЫред рдЙрдкрд▓рдмреНрдз рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдкреВрд░реА рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджреЗрдЦреЗрдВред
    4. рдЕрдкрдиреЗ Vite рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ Intlayer рдХреЛ рдПрдХреАрдХреГрдд рдХрд░реЗрдВ

      рдЕрдкрдиреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ intlayer рдкреНрд▓рдЧрдЗрди рдЬреЛрдбрд╝реЗрдВ:

      vite.config.ts
      import { tanstackStart } from "@tanstack/react-start/plugin/vite";
      import viteReact from "@vitejs/plugin-react";
      import { nitro } from "nitro/vite";
      import { defineConfig } from "vite";
      import { intlayer } from "vite-intlayer";
      
      const config = defineConfig({
        plugins: [
          nitro(),
          intlayer({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
          tanstackStart({
            router: {
              routeFileIgnorePattern:
                ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5|md|mdx|yaml|yml)$",
            },
          }),
          viteReact(),
        ],
      });
      
      export default config;
      
      intlayer() Vite рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ Intlayer рдХреЛ Vite рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдХрд╛рд╕ рдореЛрдб рдореЗрдВ рдЙрдирдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИред рдпрд╣ Vite рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рднреАрддрд░ Intlayer рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдирд╛рдо рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
    5. рд░реВрдЯ рд▓реЗрдЖрдЙрдЯ рдмрдирд╛рдПрдВ

      рд╡рд░реНрддрдорд╛рди рд▓реЛрдХреЗрд▓ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП useParams рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдФрд░ html рдЯреИрдЧ рдкрд░ lang рдФрд░ dir рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд╕реЗрдЯ рдХрд░рдХреЗ рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд░реВрдЯ рд▓реЗрдЖрдЙрдЯ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред

      src/routes/__root.tsx
      import {
        createRootRouteWithContext,
        getRouteApi,
        HeadContent,
        Scripts,
      } from "@tanstack/react-router";
      import { defaultLocale, getHTMLTextDir } from "intlayer";
      import { type ReactNode } from "react";
      import { IntlayerProvider } from "react-intlayer";
      
      const localeRoute = getRouteApi("/{-$locale}");
      
      export const Route = createRootRouteWithContext<{}>()({
        head: () => ({
          meta: [
            {
              charSet: "utf-8",
            },
            {
              content: "width=device-width, initial-scale=1",
              name: "viewport",
            },
            {
              title: "TanStack Start Starter",
            },
          ],
        }),
      
        shellComponent: RootDocument,
      });
      
      function RootDocument({ children }: { children: ReactNode }) {
        const params = localeRoute.useParams();
        const locale = params?.locale ?? defaultLocale;
      
        return (
          <html dir={getHTMLTextDir(locale)} lang={locale}>
            <head>
              <HeadContent />
            </head>
            <body>
              <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
              <Scripts />
            </body>
          </html>
        );
      }
      
    6. рд▓реЛрдХреЗрд▓ рд▓реЗрдЖрдЙрдЯ рдмрдирд╛рдПрдВ

      рдПрдХ рд▓реЗрдЖрдЙрдЯ рдмрдирд╛рдПрдВ рдЬреЛ рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ рдФрд░ рд╕рддреНрдпрд╛рдкрди рдХрд░рддрд╛ рд╣реИред

      src/routes/{-$locale}/route.tsx
      import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
      import { validatePrefix } from "intlayer";
      
      export const Route = createFileRoute("/{-$locale}")({
        beforeLoad: ({ params }) => {
          const localeParam = params.locale;
      
          // рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдВ
          const { isValid, localePrefix } = validatePrefix(localeParam);
      
          if (!isValid) {
            throw redirect({
              to: "/{-$locale}/404",
              params: { locale: localePrefix },
            });
          }
        },
        component: Outlet,
      });
      
      рдпрд╣рд╛рдБ, {-$locale} рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд░реВрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ рдЬреЛ рд╡рд░реНрддрдорд╛рди рд▓реЛрдХреЗрд▓ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдиреЛрдЯреЗрд╢рди рд╕реНрд▓реЙрдЯ рдХреЛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдмрдирд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдпрд╣ 'prefix-no-default' рдЖрджрд┐ рдЬреИрд╕реЗ рд░реВрдЯрд┐рдВрдЧ рдореЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

      рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдк рдПрдХ рд╣реА рд░реВрдЯ рдореЗрдВ рдХрдИ рдЧрддрд┐рд╢реАрд▓ рдЦрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ (рдЬреИрд╕реЗ, /{-$locale}/other-path/$anotherDynamicPath/...), рддреЛ рдпрд╣ рд╕реНрд▓реЙрдЯ рд╕рдорд╕реНрдпрд╛рдПрдБ рдкреИрджрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред 'prefix-all' рдореЛрдб рдХреЗ рд▓рд┐рдП, рдЖрдк рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рд╕реНрд▓реЙрдЯ рдХреЛ $locale рдореЗрдВ рдмрджрд▓рдирд╛ рдкрд╕рдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред 'no-prefix' рдпрд╛ 'search-params' рдореЛрдб рдХреЗ рд▓рд┐рдП, рдЖрдк рд╕реНрд▓реЙрдЯ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред

    7. рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ

      рдЕрдиреБрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛рдПрдВ рдмрдирд╛рдПрдВ рдФрд░ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░реЗрдВ:

      src/contents/page.content.ts
      import type { Dictionary } from "intlayer";
      
      import { t } from "intlayer";
      
      const appContent = {
        content: {
          links: {
            about: t({
              en: "About",
              es: "Acerca de",
              fr: "├А propos",
            }),
            home: t({
              en: "Home",
              es: "Inicio",
              fr: "Accueil",
            }),
          },
          meta: {
            title: t({
              en: "Welcome to Intlayer + TanStack Router",
              es: "Bienvenido a Intlayer + TanStack Router",
              fr: "Bienvenue ├а Intlayer + TanStack Router",
            }),
            description: t({
              en: "This is an example of using Intlayer with TanStack Router",
              es: "Este es un рдЙрджрд╛рд╣рд░рдг de uso de Intlayer con TanStack Router",
              fr: "Ceci est un exemple d'utilisation d'Intlayer avec TanStack Router",
            }),
          },
        },
        key: "app",
      } satisfies Dictionary;
      
      export default appContent;
      
      рдЖрдкрдХреА рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛рдПрдВ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдХрд╣реАрдВ рднреА рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ рдЬреИрд╕реЗ рд╣реА рд╡реЗ contentDir рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, ./app) рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИрдВред рдФрд░ рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛ рдлрд╝рд╛рдЗрд▓ рд╡рд┐рд╕реНрддрд╛рд░ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}) рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИрдВред
      рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджреЗрдЦреЗрдВред
    8. рд▓реЛрдХреЗрд▓-рдЬрд╛рдЧрд░реВрдХ рдШрдЯрдХ рдФрд░ рд╣реБрдХ рдмрдирд╛рдПрдВ

      рд▓реЛрдХреЗрд▓-рдЬрд╛рдЧрд░реВрдХ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ LocalizedLink рдШрдЯрдХ рдмрдирд╛рдПрдВ:

      src/components/localized-link.tsx
      import type { FC } from "react";
      
      import { Link, type LinkComponentProps } from "@tanstack/react-router";
      import { useLocale } from "react-intlayer";
      import { getPrefix } from "intlayer";
      
      export const LOCALE_ROUTE = "{-$locale}" as const;
      
      export type To = StripLocalePrefix<LinkComponentProps["to"]>;
      
      export type StripLocalePrefix<T extends string | undefined> = T extends
        `/${typeof LOCALE_ROUTE}/` | `/${typeof LOCALE_ROUTE}`
        ? "/"
        : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`
          ? `/${Rest}`
          : T;
      
      type LocalizedLinkProps = {
        to?: To;
      } & Omit<LinkComponentProps, "to">;
      
      export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {
        const { locale } = useLocale();
        const { localePrefix } = getPrefix(locale);
      
        return (
          <Link
            {...props}
            params={{
              locale: localePrefix,
              ...(typeof props?.params === "object" ? props?.params : {}),
            }}
            to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps["to"]}
          />
        );
      };
      

      рдЗрд╕ рдШрдЯрдХ рдХреЗ рджреЛ рдЙрджреНрджреЗрд╢реНрдп рд╣реИрдВ:

      • URL рд╕реЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ {-$locale} рдЙрдкрд╕рд░реНрдЧ рдХреЛ рд╣рдЯрд╛рдирд╛ред
      • URL рдореЗрдВ рд▓реЛрдХреЗрд▓ рдкреИрд░рд╛рдореАрдЯрд░ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдирд╛ рддрд╛рдХрд┐ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХреЗ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реАрдзреЗ рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд░реВрдЯ рдкрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдд рд╣реЛред

      рдлрд┐рд░ рд╣рдо рдкреНрд░реЛрдЧреНрд░рд╛рдореЗрдЯрд┐рдХ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ useLocalizedNavigate рд╣реБрдХ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:

      src/hooks/useLocalizedNavigate.tsx
      import { useNavigate } from "@tanstack/react-router";
      import { getPrefix } from "intlayer";
      import { useLocale } from "react-intlayer";
      import type { StripLocalePrefix } from "@/components/localized-link";
      import type { FileRouteTypes } from "@/routeTree.gen";
      
      type NavigateFn = ReturnType<typeof useNavigate>;
      type BaseNavigateOptions = Parameters<NavigateFn>[0];
      
      type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;
      
      export type LocalizedNavigateOptions = Omit<
        BaseNavigateOptions,
        "to" | "params"
      > & {
        to: LocalizedTo;
        params?: Omit<NonNullable<BaseNavigateOptions["params"]>, "locale">;
      };
      
      type LocalizedNavigate = (
        options: LocalizedNavigateOptions
      ) => ReturnType<NavigateFn>;
      
      export const useLocalizedNavigate = () => {
        const navigate = useNavigate();
      
        const { locale } = useLocale();
      
        const localizedNavigate: LocalizedNavigate = (args: any) => {
          const { localePrefix } = getPrefix(locale);
      
          if (typeof args === "string") {
            return navigate({
              to: `/${LOCALE_ROUTE}${args}`,
              params: { locale: localePrefix },
            });
          }
      
          const { to, ...rest } = args;
      
          const localizedTo = `/${LOCALE_ROUTE}${to}` as any;
      
          return navigate({
            to: localizedTo,
            params: { locale: localePrefix, ...rest } as any,
          });
        };
      
        return localizedNavigate;
      };
      
    9. рдЕрдкрдиреЗ рдкреГрд╖реНрдареЛрдВ рдореЗрдВ Intlayer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

      рдХрдВрдкреЛрдиреЗрдВрдЯ рдХреЗ рднреАрддрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ useIntlayer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ: рдпрд╣ рдХрдВрдЯреЗрдВрдЯ рдкрдврд╝рдиреЗ рдХрд╛ рдЕрдиреБрд╢рдВрд╕рд┐рдд рддрд░реАрдХрд╛ рд╣реИ, рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдЗрд╕реЗ рд░реЗрдВрдбрд░ рд╣реЛ рд░рд╣реЗ рд▓реЛрдХреЗрд▓ рдкрд░ рд╣рд▓ рдХрд░ рджреЗрддрд╛ рд╣реИред getIntlayer / getIntlayerAsync рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ React рдЯреНрд░реА рдХреЗ рдмрд╛рд╣рд░ рдХрд░реЗрдВ: рд░реВрдЯ рдХреЗ head, рд▓реЛрдбрд░ рдФрд░ рд╕рд░реНрд╡рд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВред

      рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЕрдкрдиреЗ рд╕рд╛рдордЧреНрд░реА рд╢рдмреНрджрдХреЛрд╢реЛрдВ рддрдХ рдкрд╣реБрдВрдЪреЗрдВ:

      рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд╣реЛрдо рдкреЗрдЬ

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/react-router";
      import { useIntlayer } from "react-intlayer";
      
      import LocaleSwitcher from "@/components/locale-switcher";
      import { LocalizedLink } from "@/components/localized-link";
      import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
      });
      
      function RouteComponent() {
        const content = useIntlayer("app");
        const navigate = useLocalizedNavigate();
      
        return (
          <div>
            <div>
              {content.title}
              <LocaleSwitcher />
              <div>
                <LocalizedLink to="/">{content.links.home}</LocalizedLink>
                <LocalizedLink to="/about">{content.links.about}</LocalizedLink>
              </div>
              <div>
                <button onClick={() => navigate({ to: "/" })}>
                  {content.links.home}
                </button>
                <button onClick={() => navigate({ to: "/about" })}>
                  {content.links.about}
                </button>
              </div>
            </div>
          </div>
        );
      }
      

      рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдХрдВрдЯреЗрдВрдЯ рдХреЛ string attribute рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ 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 hook рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджреЗрдЦреЗрдВред
    10. рдПрдХ рд▓реЛрдХреЗрд▓ рд╕реНрд╡рд┐рдЪрд░ рдХрдВрдкреЛрдиреЗрдВрдЯ рдмрдирд╛рдПрдВ

      рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рднрд╛рд╖рд╛ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдВрдкреЛрдиреЗрдВрдЯ рдмрдирд╛рдПрдВ:

      src/components/locale-switcher.tsx
      import { useLocation } from "@tanstack/react-router";
      import {
        getHTMLTextDir,
        getLocaleName,
        getPathWithoutLocale,
        getPrefix,
        Locales,
      } from "intlayer";
      import type { FC } from "react";
      import { useLocale } from "react-intlayer";
      
      import { LocalizedLink, type To } from "./localized-link";
      
      export const LocaleSwitcher: FC = () => {
        const { pathname } = useLocation();
      
        const { availableLocales, locale, setLocale } = useLocale();
      
        const pathWithoutLocale = getPathWithoutLocale(pathname);
      
        return (
          <ol>
            {availableLocales.map((localeEl) => (
              <li key={localeEl}>
                <LocalizedLink
                  aria-current={localeEl === locale ? "page" : undefined}
                  onClick={() => setLocale(localeEl)}
                  params={{ locale: getPrefix(localeEl).localePrefix }}
                  to={pathWithoutLocale as To}
                >
                  <span>
                    {/* рд▓реЛрдХреЗрд▓ - рдЬреИрд╕реЗ FR */}
                    {localeEl}
                  </span>
                  <span>
                    {/* рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд▓реЛрдХреЗрд▓ рдореЗрдВ рднрд╛рд╖рд╛ - рдЬреИрд╕реЗ Fran├зais */}
                    {getLocaleName(localeEl, locale)}
                  </span>
                  <span dir={getHTMLTextDir(localeEl)} lang={localeEl}>
                    {/* рд╡рд░реНрддрдорд╛рди рд▓реЛрдХреЗрд▓ рдореЗрдВ рднрд╛рд╖рд╛ - рдЬреИрд╕реЗ Franc├йs рд╡рд░реНрддрдорд╛рди рд▓реЛрдХреЗрд▓ рдХреЛ Locales.SPANISH рдкрд░ рд╕реЗрдЯ рдХрд░рдХреЗ */}
                    {getLocaleName(localeEl)}
                  </span>
                  <span dir="ltr" lang={Locales.ENGLISH}>
                    {/* рдЕрдВрдЧреНрд░реЗрдЬреА рдореЗрдВ рднрд╛рд╖рд╛ - рдЬреИрд╕реЗ French */}
                    {getLocaleName(localeEl, Locales.ENGLISH)}
                  </span>
                </LocalizedLink>
              </li>
            ))}
          </ol>
        );
      };
      
      useLocale hook рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджреЗрдЦреЗрдВред
    11. HTML рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдкреНрд░рдмрдВрдзрди

      рдЬреИрд╕рд╛ рдХрд┐ рд╕реНрдЯреЗрдк 5 рдореЗрдВ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЖрдк рдЕрдкрдиреЗ рд░реВрдЯ рдХрдВрдкреЛрдиреЗрдВрдЯ рдореЗрдВ useParams рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ html рдЯреИрдЧ рдХреА lang рдФрд░ dir рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕рд╣реА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рджреЛрдиреЛрдВ рдкрд░ рд╕реЗрдЯ рд╣реЛрдВред

      src/routes/__root.tsx
      const localeRoute = getRouteApi("/{-$locale}");
      
      function RootDocument({ children }: { children: ReactNode }) {
        const params = localeRoute.useParams();
        const locale = params?.locale ?? defaultLocale;
      
        return (
          <html dir={getHTMLTextDir(locale)} lang={locale}>
            {/* ... */}
          </html>
        );
      }
      
    12. рдорд┐рдбрд▓рд╡реЗрдпрд░ рдЬреЛрдбрд╝реЗрдВ

      рдЖрдк рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рд░реВрдЯрд┐рдВрдЧ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП intlayerProxy рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ plugin рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ URL рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡рд░реНрддрдорд╛рди рд▓реЛрдХреЗрд▓ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдЧрд╛ рдФрд░ рдЙрдкрдпреБрдХреНрдд рд▓реЛрдХреЗрд▓ рдХреБрдХреА рд╕реЗрдЯ рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рдХреЛрдИ рд▓реЛрдХреЗрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ plugin рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рднрд╛рд╖рд╛ рд╡рд░реАрдпрддрд╛рдУрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рд▓реЛрдХреЗрд▓ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рдХреЛрдИ рд▓реЛрдХреЗрд▓ рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд▓реЛрдХреЗрд▓ рдкрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдЧрд╛ред

      рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ production рдореЗрдВ intlayerProxy рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ vite-intlayer package рдХреЛ devDependencies рд╕реЗ dependencies рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
      Intlayer v9 рдХреЗ рдмрд╛рдж рд╕реЗ, intlayerProxy() рдХреЛ рд╕реАрдзреЗ intlayer() plugin рдореЗрдВ bundled рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ routing.enableProxy рд╡рд┐рдХрд▓реНрдк (true by default) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдХреНрд╖рдо рд╣реИред рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЧрдП рдЕрдиреБрд╕рд╛рд░ рдЗрд╕реЗ рдЕрд▓рдЧ рд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рдЕрдм рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИ: рдпрд╣ backward compatibility рдХреЗ рд▓рд┐рдП рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЙрди рд╕реЗрдЯрдЕрдк рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЗрдВ plugin order рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред opt out рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП routing.enableProxy: false рд╕реЗрдЯ рдХрд░реЗрдВред v9 release notes рджреЗрдЦреЗрдВред
      vite.config.ts
      import { tanstackStart } from "@tanstack/react-start/plugin/vite";
      import viteReact from "@vitejs/plugin-react";
      import { nitro } from "nitro/vite";
      import { defineConfig } from "vite";
      import { intlayer } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [
          nitro(),
          intlayer({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
          tanstackStart({
            router: {
              routeFileIgnorePattern:
                ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5|md|mdx|yaml|yml)$",
            },
          }),
          viteReact(),
        ],
      });
      
    13. рдЕрдкрдиреЗ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЛ рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХреГрдд рдХрд░реЗрдВ

      getIntlayer merged dictionary рдХреЗ рд╡рд┐рд░реБрджреНрдз synchronously resolve рдХрд░рддрд╛ рд╣реИ, рд╡рд╣ рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдШреЛрд╖рд┐рдд рд▓реЛрдХреЗрд▓ рдХреЛ рд░рдЦрддрд╛ рд╣реИред head synchronous рд░рд╣рддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рднреА await рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рдВрдкреВрд░реНрдг рдмрд╣реБрднрд╛рд╖реА dictionary рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рднреЗрдЬреЗ рдЧрдП route chunk рдореЗрдВ pull рдХреА рдЬрд╛рддреА рд╣реИред

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/react-router";
      import {
        defaultLocale,
        getIntlayer,
        getLocalizedUrl,
        localeMap,
      } from "intlayer";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
        head: ({ params }) => {
          const { locale = defaultLocale } = params;
          const path = "/"; // рдЗрд╕ route рдХреЗ рд▓рд┐рдП рдкрде
      
          const metaContent = getIntlayer("app", locale);
      
          return {
            links: [
              // Canonical link: рд╡рд░реНрддрдорд╛рди рд╕реНрдерд╛рдиреАрдпрдХреГрдд рдкреГрд╖реНрда рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░рддрд╛ рд╣реИ
              { rel: "canonical", href: getLocalizedUrl(path, locale) },
      
              // Hreflang: Google рдХреЛ рд╕рднреА рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдВ
              ...localeMap(({ locale: mapLocale }) => ({
                rel: "alternate",
                hrefLang: mapLocale,
                href: getLocalizedUrl(path, mapLocale),
              })),
      
              // x-default: рдЕрдореЗрд▓рд┐рдд рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП
              // рдбрд┐рдлрд╝реЙрд▓реНрдЯ fallback рд▓реЛрдХреЗрд▓ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ (рдЖрдорддреМрд░ рдкрд░ рдЖрдкрдХреА рдкреНрд░рд╛рдердорд┐рдХ рднрд╛рд╖рд╛)
              {
                rel: "alternate",
                hrefLang: "x-default",
                href: getLocalizedUrl(path, defaultLocale),
              },
            ],
            meta: [
              { title: metaContent.title },
              { name: "description", content: metaContent.meta.description },
            ],
          };
        },
      });
      

      рдЫреЛрдЯреЗ рдореЗрдЯрд╛рдбреЗрдЯрд╛ dictionaries, рдХреБрдЫ рд▓реЛрдХреЗрд▓ рдХреЗ рд▓рд┐рдП, рдпрд╛ prototyping рдХреЗ рджреМрд░рд╛рди рд╕рд░реНрд╡реЛрддреНрддрдо рд╣реИред

      getIntlayerAsync (v9.4 рд╕реЗ рдЙрдкрд▓рдмреНрдз) getIntlayer рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди build plugin рдЗрд╕реЗ merged dictionary рдХреЗ рдмрдЬрд╛рдп .intlayer/dynamic_dictionaries/ рдореЗрдВ per-locale chunk рдХреА рдУрд░ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдПрдХ рдкреГрд╖реНрда рдЗрд╕рд▓рд┐рдП рдХреЗрд╡рд▓ рдЙрд╕ рд▓реЛрдХреЗрд▓ рдХреЛ рдЬрд╣рд╛рдЬ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдпрд╣ render рдХрд░рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рд╡рд╣ chunk on demand рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИ, head async рдмрди рдЬрд╛рддрд╛ рд╣реИ:

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/react-router";
      import {
        defaultLocale,
        getIntlayerAsync,
        getLocalizedUrl,
        localeMap,
      } from "intlayer";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
        head: async ({ params }) => {
          const { locale = defaultLocale } = params;
          const path = "/"; // рдЗрд╕ route рдХреЗ рд▓рд┐рдП рдкрде
      
          const metaContent = await getIntlayerAsync("app", locale);
      
          return {
            links: [
              // Canonical link: рд╡рд░реНрддрдорд╛рди рд╕реНрдерд╛рдиреАрдпрдХреГрдд рдкреГрд╖реНрда рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░рддрд╛ рд╣реИ
              { rel: "canonical", href: getLocalizedUrl(path, locale) },
      
              // Hreflang: Google рдХреЛ рд╕рднреА рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдВ
              ...localeMap(({ locale: mapLocale }) => ({
                rel: "alternate",
                hrefLang: mapLocale,
                href: getLocalizedUrl(path, mapLocale),
              })),
      
              // x-default: рдЕрдореЗрд▓рд┐рдд рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП
              // рдбрд┐рдлрд╝реЙрд▓реНрдЯ fallback рд▓реЛрдХреЗрд▓ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ (рдЖрдорддреМрд░ рдкрд░ рдЖрдкрдХреА рдкреНрд░рд╛рдердорд┐рдХ рднрд╛рд╖рд╛)
              {
                rel: "alternate",
                hrefLang: "x-default",
                href: getLocalizedUrl(path, defaultLocale),
              },
            ],
            meta: [
              { title: metaContent.title },
              { name: "description", content: metaContent.meta.description },
            ],
          };
        },
      });
      
      рдпрджрд┐ рдПрдХ head рдХрдИ dictionaries рдХреЛ рдкрдврд╝рддрд╛ рд╣реИ, рддреЛ рдЙрдиреНрд╣реЗрдВ Promise.all рдХреЗ рд╕рд╛рде resolve рдХрд░реЗрдВ: рдкреНрд░рддреНрдпреЗрдХ getIntlayerAsync рдХреЛ рдЕрдкрдиреА line рдкрд░ await рдХрд░рдиреЗ рд╕реЗ requests рдХреЛ chain рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рди рдХрд┐ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

      trade-off: рдЧрддрд┐рд╢реАрд▓ import рдХреЛ head рдЪрд▓рддреЗ рд╕рдордп resolve рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, document render рдХреЗ critical path рдкрд░ред рдПрдХ cold route рдкрд░ рдпрд╣ head рдХреЛ рдХреБрдЫ рдорд┐рд▓реАрд╕реЗрдХрдВрдб рд╕реЗ рджреЗрд░реА рдХрд░рддрд╛ рд╣реИ рдФрд░ LCP рдХреЛ рдереЛрдбрд╝рд╛ degrade рдХрд░ рд╕рдХрддрд╛ рд╣реИред

      route loader рдореЗрдВ dictionary рдХреЛ resolve рдХрд░реЗрдВ рдФрд░ head рдореЗрдВ loaderData рд╕реЗ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдкрдврд╝реЗрдВред matched routes рдХреЗ loaders рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЪрд▓рддреЗ рд╣реИрдВ, рдФрд░ staleTime: Infinity TanStack Router рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рдХрднреА рднреА stale рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП per-locale chunk рдПрдХ рдмрд╛рд░ resolve рд╣реЛрддрд╛ рд╣реИ рдФрд░ router cache рд╕реЗ рдмрд╛рдж рдореЗрдВ served рд╣реЛрддрд╛ рд╣реИ, head рдХреЛ synchronous рдЫреЛрдбрд╝рддрд╛ рд╣реИред

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/react-router";
      import {
        defaultLocale,
        getIntlayerAsync,
        getLocalizedUrl,
        localeMap,
      } from "intlayer";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
        // рдЕрдиреНрдп matched routes рдХреЗ рд╕рд╛рде рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ resolved, head critical path рд╕реЗ рдмрд╛рд╣рд░
        loader: async ({ params }) => {
          const { locale = defaultLocale } = params;
      
          return { metaContent: await getIntlayerAsync("app", locale) };
        },
        // рджрд┐рдП рдЧрдП рд▓реЛрдХреЗрд▓ рдХреЗ рд▓рд┐рдП dictionary рдХрднреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ: chunk рдХреЛ рдПрдХ рдмрд╛рд░ resolve рдХрд░реЗрдВ
        staleTime: Infinity,
        head: ({ params, loaderData }) => {
          const { locale = defaultLocale } = params;
          const path = "/"; // рдЗрд╕ route рдХреЗ рд▓рд┐рдП рдкрде
      
          return {
            links: [
              // Canonical link: рд╡рд░реНрддрдорд╛рди рд╕реНрдерд╛рдиреАрдпрдХреГрдд рдкреГрд╖реНрда рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░рддрд╛ рд╣реИ
              { rel: "canonical", href: getLocalizedUrl(path, locale) },
      
              // Hreflang: Google рдХреЛ рд╕рднреА рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдВ
              ...localeMap(({ locale: mapLocale }) => ({
                rel: "alternate",
                hrefLang: mapLocale,
                href: getLocalizedUrl(path, mapLocale),
              })),
      
              // x-default: рдЕрдореЗрд▓рд┐рдд рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП
              // рдбрд┐рдлрд╝реЙрд▓реНрдЯ fallback рд▓реЛрдХреЗрд▓ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ (рдЖрдорддреМрд░ рдкрд░ рдЖрдкрдХреА рдкреНрд░рд╛рдердорд┐рдХ рднрд╛рд╖рд╛)
              {
                rel: "alternate",
                hrefLang: "x-default",
                href: getLocalizedUrl(path, defaultLocale),
              },
            ],
            meta: [
              { title: loaderData?.metaContent.title },
              {
                name: "description",
                content: loaderData?.metaContent.meta.description,
              },
            ],
          };
        },
      });
      
      head рдХреЛ loader settle рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ call рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП loaderData рдХреЛ рд╕рдВрднрд╡рддрдГ undefined рдХреЗ рд░реВрдк рдореЗрдВ typed рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред optional chaining рд░рдЦреЗрдВ, рдпрд╛ рдПрдХ fallback title return рдХрд░реЗрдВред

      рдЖрдк head critical path рдкрд░ рдЗрд╕рдХреА cost рджрд┐рдП рдмрд┐рдирд╛ per-locale chunk рд░рдЦрддреЗ рд╣реИрдВред рдХреАрдордд developer experience рд╣реИ: content рдХреЛ explicitly loader рд╕реЗ head рдореЗрдВ loaderData рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ threaded рд╣реЛрдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред

      рдХрд┐рд╕ resolution рдХреЛ рдЪреБрдирдирд╛ рдЪрд╛рд╣рд┐рдП?

      Static resolutionDynamic resolutionCached dynamic resolution
      APIgetIntlayergetIntlayerAsync (v9.4+)getIntlayerAsync in loader (v9.4+)
      head signaturesynchronousasyncsynchronous, reads loaderData
      Locales shippedevery declared localerequested locale onlyrequested locale only
      Client navigationsnothing to resolvere-entered on every matchserved from the router cache
      Developer experiencesimplestone awaitcontent threaded through loaderData
    14. рдЕрдкрдиреЗ server actions рдореЗрдВ locale рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

      рдЖрдк рдЕрдкрдиреЗ server actions рдпрд╛ API endpoints рдХреЗ рдЕрдВрджрд░ рд╕реЗ current locale рдХреЛ access рдХрд░рдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдЗрд╕реЗ intlayer рд╕реЗ getLocale helper рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

      рдпрд╣рд╛рдБ TanStack Start рдХреЗ server functions рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

      src/routes/{-$locale}/index.tsx
      import { createServerFn } from "@tanstack/react-start";
      import {
        getRequestHeader,
        getRequestHeaders,
      } from "@tanstack/react-start/server";
      import { getCookie, getIntlayer, getLocale } from "intlayer";
      
      export const getLocaleServer = createServerFn().handler(async () => {
        const locale = await getLocale({
          // рдЕрдиреБрд░реЛрдз рд╕реЗ cookie рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ: 'INTLAYER_LOCALE')
          getCookie: (name) => {
            const cookieString = getRequestHeader("cookie");
      
            return getCookie(name, cookieString);
          },
          // рдЕрдиреБрд░реЛрдз рд╕реЗ header рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ: 'x-intlayer-locale')
          // Accept-Language negotiation рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ fallback
          getHeader: (name) => getRequestHeader(name),
        });
      
        // getIntlayerAsync() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреБрдЫ content рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
        const content = getIntlayer("app", locale);
      
        return { locale, content };
      });
      
    15. рдирд╣реАрдВ рдорд┐рд▓реЗ рдкреГрд╖реНрдареЛрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░реЗрдВ

      рдЬрдм рдХреЛрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЧреИрд░-рдореМрдЬреВрдж рдкреГрд╖реНрда рдкрд░ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдк рдПрдХ рдХрд╕реНрдЯрдо рдирд╣реАрдВ рдорд┐рд▓рд╛ рдкреГрд╖реНрда рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдкреГрд╖реНрда рдХреЗ рдЯреНрд░рд┐рдЧрд░ рд╣реЛрдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

      рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧреЛрдВ рдХреЗ рд╕рд╛рде TanStack Router рдХреЗ 404 рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛ рд╕рдордЭрдирд╛

      TanStack Router рдореЗрдВ, рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд░реВрдЯреНрд╕ рдХреЗ рд╕рд╛рде 404 рдкреГрд╖реНрдареЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБ-рд╕реНрддрд░реАрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ:

      1. рд╕рдорд░реНрдкрд┐рдд 404 рд░реВрдЯ: 404 UI рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░реВрдЯ
      2. рд░реВрдЯ-рд╕реНрддрд░реАрдп рд╕рддреНрдпрд╛рдкрди: рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧреЛрдВ рдХреЛ рдорд╛рдиреНрдп рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдорд╛рдиреНрдп рдХреЛ 404 рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ
      3. рдХреИрдЪ-рдСрд▓ рд░реВрдЯ: рд▓реЛрдХреЗрд▓ рдЦрдВрдб рдХреЗ рднреАрддрд░ рдХрд┐рд╕реА рднреА рдмреЗрдореЗрд▓ рдкрде рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИ
      src/routes/{-$locale}/404.tsx
      import { createFileRoute } from "@tanstack/react-router";
      
      // рдпрд╣ рдПрдХ рд╕рдорд░реНрдкрд┐рдд /[locale]/404 рд░реВрдЯ рдмрдирд╛рддрд╛ рд╣реИ
      // рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдкреНрд░рддреНрдпрдХреНрд╖ рд░реВрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдФрд░ рдЕрдиреНрдп рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдШрдЯрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдпрд╛рдд рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
      export const Route = createFileRoute("/{-$locale}/404")({
        component: NotFoundComponent,
      });
      
      // рдЕрд▓рдЧ рд╕реЗ рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рддрд╛рдХрд┐ рдЗрд╕реЗ notFoundComponent рдФрд░ рдХреИрдЪ-рдСрд▓ рд░реВрдЯреНрд╕ рдореЗрдВ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ
      export function NotFoundComponent() {
        return (
          <div>
            <h1>404</h1>
          </div>
        );
      }
      
      src/routes/{-$locale}/route.tsx
      import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
      import { validatePrefix } from "intlayer";
      import { NotFoundComponent } from "./404";
      
      export const Route = createFileRoute("/{-$locale}")({
        // beforeLoad рд░реВрдЯ рд░реЗрдВрдбрд░ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЪрд▓рддрд╛ рд╣реИ (рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рджреЛрдиреЛрдВ рдкрд░)
        // рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрджрд░реНрд╢ рд╕реНрдерд╛рди рд╣реИ
        beforeLoad: ({ params }) => {
          const localeParam = params.locale;
      
          // validatePrefix рдЬрд╛рдБрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд▓реЛрдХреЗрд▓ рдЖрдкрдХреЗ intlayer рдХреЙрдиреНрдлрд╝рд┐рдЧ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдорд╛рдиреНрдп рд╣реИ
          const { isValid, localePrefix } = validatePrefix(localeParam);
      
          if (!isValid) {
            // рдЕрдорд╛рдиреНрдп рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ - рдорд╛рдиреНрдп рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ рдХреЗ рд╕рд╛рде 404 рдкреГрд╖реНрда рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реЗрдВ
            throw redirect({
              to: "/{-$locale}/404",
              params: { locale: localePrefix },
            });
          }
        },
        component: Outlet,
        // notFoundComponent рддрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдХреЛрдИ рдЪрд╛рдЗрд▓реНрдб рд░реВрдЯ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реЛрддрд╛
        // рдЙрджрд╛., /en/non-existent-page /en рд▓реЗрдЖрдЙрдЯ рдХреЗ рднреАрддрд░ рдЗрд╕реЗ рдЯреНрд░рд┐рдЧрд░ рдХрд░рддрд╛ рд╣реИ
        notFoundComponent: NotFoundComponent,
      });
      
      src/routes/{-$locale}/$.tsx
      import { createFileRoute } from "@tanstack/react-router";
      
      import { NotFoundComponent } from "./404";
      
      // $ (рд╕реНрдкреНрд▓реИрдЯ/рдХреИрдЪ-рдСрд▓) рд░реВрдЯ рдХрд┐рд╕реА рднреА рдкрде рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬреЛ рдЕрдиреНрдп рд░реВрдЯреНрд╕ рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛
      // рдЙрджрд╛., /en/some/deeply/nested/invalid/path
      // рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдХреЗрд▓ рдХреЗ рднреАрддрд░ рд╕рднреА рдмреЗрдореЗрд▓ рдкрде 404 рдкреГрд╖реНрда рджрд┐рдЦрд╛рддреЗ рд╣реИрдВ
      // рдЗрд╕рдХреЗ рдмрд┐рдирд╛, рдмреЗрдореЗрд▓ рдЧрд╣рд░реЗ рдкрде рдПрдХ рдЦрд╛рд▓реА рдкреГрд╖реНрда рдпрд╛ рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ
      export const Route = createFileRoute("/{-$locale}/$")({
        component: NotFoundComponent,
      });
      
    16. рдЕрдкрдиреЗ рдШрдЯрдХреЛрдВ рдХреА рд╕рд╛рдордЧреНрд░реА рдирд┐рдХрд╛рд▓реЗрдВ

      рд╡реИрдХрд▓реНрдкрд┐рдХ

      isOptional={true}>

      рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдореМрдЬреВрджрд╛ рдХреЛрдбрдмреЗрд╕ рд╣реИ, рддреЛ рд╣рдЬрд╛рд░реЛрдВ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рд╕рдордп рд▓реЗрдиреЗ рд╡рд╛рд▓рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

      рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, Intlayer рдЖрдкрдХреЗ рдШрдЯрдХреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдФрд░ рд╕рд╛рдордЧреНрд░реА рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдВрдкрд╛рдЗрд▓рд░ / рдПрдХреНрд╕рдЯреНрд░реИрдХреНрдЯрд░ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реИред

      рдЗрд╕реЗ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрдкрдиреА intlayer.config.ts рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдПрдХ compiler рдЕрдиреБрднрд╛рдЧ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:

      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.

      intlayerCompiler рдкреНрд▓рдЧрдЗрди рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ vite.config.ts рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ:

      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
      
    17. рдкреВрд░реНрд╡-рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВ рдФрд░ рд╕рд╛рдЗрдЯрдореИрдк рдЬрдирд░реЗрдЯ рдХрд░реЗрдВ

      Intlayer рдореЗрдВ рдПрдХ built-in sitemap generator рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рдиреА рд╕реЗ sitemap рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рдпрд╣ localized routes рдХреЛ handle рдХрд░рддрд╛ рд╣реИ рдФрд░ search engines рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ metadata рдЬреЛрдбрд╝рддрд╛ рд╣реИред

      Intlayer рджреНрд╡рд╛рд░рд╛ generated sitemap xhtml:link namespace (Hreflang XML Extensions) рдХреЛ support рдХрд░рддрд╛ рд╣реИред Default sitemap generators рдХреЗ рд╡рд┐рдкрд░реАрдд рдЬреЛ рдХреЗрд╡рд▓ raw URLs list рдХрд░рддреЗ рд╣реИрдВ, Intlayer automatically рдПрдХ page рдХреЗ рд╕рднреА language versions рдХреЗ рдмреАрдЪ required bidirectional links create рдХрд░рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, /about, /about?lang=fr, рдФрд░ /about?lang=es)ред рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ search engines рд╕рд╣реА language version рдХреЛ рд╕рд╣реА audience рдХреЛ correctly index рдФрд░ serve рдХрд░реЗрдВред

      рдЗрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдЕрдкрдиреА vite.config.ts рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рддрд╛рдХрд┐ рдЖрдкрдХреЗ рд╕реНрдерд╛рдиреАрдпрдХреГрдд routes рдХреЗ рд▓рд┐рдП рдкреНрд░реА-рд░реЗрдВрдбрд░рд┐рдВрдЧ рд╕рдХреНрд╖рдо рд╣реЛ рд╕рдХреЗ рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ TanStack Start sitemap рдЬрдирд░реЗрд╢рди рдХреЛ рдЕрдХреНрд╖рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред

      vite.config.ts
      import { localeFlatMap } from "intlayer";
      // ... рдЕрдиреНрдп imports
      
      export const pathList = ["", "/about", "/404"];
      
      const localizedPages = localeFlatMap(({ urlPrefix }) =>
        pathList.map((path) => ({
          path: `${urlPrefix}${path}`,
          prerender: {
            enabled: true,
          },
        }))
      );
      
      export default defineConfig({
        plugins: [
          // ... рдЕрдиреНрдп plugins
          tanstackStart({
            // ... рдЕрдиреНрдп config
            sitemap: {
              enabled: false,
            },
            prerender: {
              enabled: true,
              crawlLinks: false,
              concurrency: 10,
            },
            pages: localizedPages,
          }),
        ],
      });
      

      рдлрд┐рд░, рдПрдХ src/routes/sitemap[.]xml.ts route рдмрдирд╛рдПрдВ рдЬреЛ generateSitemap function рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:

      src/routes/sitemap[.]xml.ts
      import { createFileRoute } from "@tanstack/react-router";
      import { generateSitemap } from "intlayer";
      
      export const Route = createFileRoute("/sitemap.xml")({
        server: {
          handlers: {
            GET: async () => {
              const sitemap = generateSitemap(
                [
                  { path: "/", changefreq: "daily", priority: 1.0 },
                  { path: "/about", changefreq: "monthly", priority: 0.8 },
                ],
                { siteUrl: "https://example.com" }
              );
      
              return new Response(sitemap, {
                headers: { "Content-Type": "application/xml" },
              });
            },
          },
        },
      });
      
    18. TypeScript рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ

      Intlayer module augmentation рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ TypeScript рдХреЗ рд▓рд╛рдн рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЗ codebase рдХреЛ рдордЬрдмреВрдд рдмрдирд╛рддрд╛ рд╣реИред

      рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреА TypeScript рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди autogenerated рдкреНрд░рдХрд╛рд░ рд╢рд╛рдорд┐рд▓ рдХрд░рддреА рд╣реИ:

      tsconfig.json
      {
        // ... рдЖрдкрдХреА рдореМрдЬреВрджрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
        include: [
          // ... рдЖрдкрдХреА рдореМрдЬреВрджрд╛ includes
          ".intlayer/**/*.ts", // рдСрдЯреЛ-рдЬреЗрдирд░реЗрдЯ рдХрд┐рдП рдЧрдП types рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ
        ],
      }
      

    Git рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди

    Intlayer рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ Git рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдХрдорд┐рдЯ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

    рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрдкрдиреА .gitignore рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рд░реНрджреЗрд╢ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:

    .gitignore
    # Intlayer рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ
    .intlayer
    

    VS Code Extension

    Intlayer рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ development experience рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк official Intlayer VS Code Extension рдХреЛ install рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

    рдпрд╣ extension рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:

    • Autocompletion translation keys рдХреЗ рд▓рд┐рдПред
    • Real-time error detection missing translations рдХреЗ рд▓рд┐рдПред
    • Inline previews translated content рдХрд╛ред
    • Quick actions рдЖрд╕рд╛рдиреА рд╕реЗ translations рдмрдирд╛рдиреЗ рдФрд░ update рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

    Extension рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП, Intlayer VS Code Extension documentation рджреЗрдЦреЗрдВред

    рдЖрдЧреЗ рдмрдврд╝реЗрдВ

    рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк visual editor рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ CMS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрд╛рд╣рд░реАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

    рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╕рдВрджрд░реНрдн

    рдЕрдХреНрд╕рд░ рдкреВрдЫреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди

    TanStack Start рдХреА рдЕрдкрдиреА рдХреЛрдИ i18n рдкрд░рдд рдирд╣реАрдВ рд╣реИ:

    • i18next / react-i18next рдФрд░ react-intl: рд░рдирдЯрд╛рдЗрдо JSON рд▓реЛрдбрд┐рдВрдЧ рд╡рд╛рд▓реА рд▓рд╛рдЗрдмреНрд░реЗрд░реАред
    • Intlayer: SSR рдФрд░ SSG рд╕рдорд░реНрдерди, рдШрдЯрдХ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдШреЛрд╖рдгрд╛, рдкреВрд░реНрдг TypeScript рдкреНрд░рдХрд╛рд░, AI рдЕрдиреБрд╡рд╛рдж рдФрд░ рд╡рд┐рдЬрд╝реБрдЕрд▓ рдПрдбрд┐рдЯрд░ред

    Intlayer рдХреНрдпреЛрдВ рдЪреБрдиреЗрдВ рджреЗрдЦреЗрдВред

    рдиреЗрдорд╕реНрдкреЗрд╕-рдЖрдзрд╛рд░рд┐рдд рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдХрдо, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдкреГрд╖реНрда рдХрднреА рднреА рдЙрд╕ рдХреИрдЯрд▓реЙрдЧ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╡рд╣ рд░реЗрдВрдбрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдмрд┐рд▓реНрдб-рдЯрд╛рдЗрдо рдХрдВрдкрд╛рдЗрд▓рд░ useIntlayer рдХреЙрд▓ рдХреЛ рдШрдЯрдХ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╕рдЯреАрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рд╕реЗ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЧрддрд┐рд╢реАрд▓ рд╢рдмреНрджрдХреЛрд╢ рд╢реЗрд╖ рдХреЛ рдкреНрд░рддрд┐ рд▓реЛрдХреЗрд▓ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдмрдВрдбрд▓ 50% рддрдХ рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдмрдВрдбрд▓ рдЕрдиреБрдХреВрд▓рди рдФрд░ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рджреЗрдЦреЗрдВред

    рд╣рд╛рдБ, рдФрд░ рдЗрд╕рдХреЗ рджреЛ рд░рд╛рд╕реНрддреЗ рд╣реИрдВред рдЖрдк react-i18next рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЧрд╛рдЗрдб рдпрд╛ i18next рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЧрд╛рдЗрдб рдХреЗ рд╕рд╛рде content рдХреЛ рдзреАрд░реЗ-рдзреАрд░реЗ рдорд╛рдЗрдЧреНрд░реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╛ рдЖрдк рдЕрдкрдиреА рдореМрдЬреВрджрд╛ API рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрдирд╛рдП рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ: рд╕рдВрдЧрддрддрд╛ рдПрдбреЗрдкреНрдЯрд░ react-i18next, react-intl рдФрд░ i18next рдЬреИрд╕реА рдмрд┐рд▓реНрдХреБрд▓ рд╡рд╣реА API рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди Intlayer dictionaries рджреНрд╡рд╛рд░рд╛ served, рдЗрд╕рд▓рд┐рдП рдХреЗрд╡рд▓ imports рдмрджрд▓рддреЗ рд╣реИрдВ рдФрд░ component code рдирд╣реАрдВ рдмрджрд▓рддрд╛ред

    рд╣рд╛рдБред sync JSON plugin рдЖрдкрдХреА /messages/{locale}/{namespace}.json рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рддреНрдп рдХрд╛ рд╕реНрд░реЛрдд рдмрдирд╛рдП рд░рдЦрддрд╛ рд╣реИ рдФрд░ рджреЛрдиреЛрдВ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рдЙрдирд╕реЗ Intlayer dictionaries рдмрдирд╛рддрд╛ рд╣реИред sync PO plugin gettext catalogs рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рд╣реА рдХрд░рддрд╛ рд╣реИ, рдФрд░ per locale files рдЖрдкрдХреЛ locales рдХреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рдореВрд╣реАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рднрд╛рд╖рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ content рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рджреЗрддреЗ рд╣реИрдВред

    рдирд╣реАрдВред npx intlayer extract рдЪрд▓рд╛рдПрдВ рдФрд░ Intlayer рдЖрдкрдХреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдкрдврд╝рддрд╛ рд╣реИ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрдХреВрд▓ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдПрдХ .content рдлрд╝рд╛рдЗрд▓ рд▓рд┐рдЦрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЖрдк рдХреИрдЯрд▓реЙрдЧ рдореЗрдВ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХреЙрдкреА рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдПрдХ diff рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВред

    рдкреВрд░реНрдг рд╕реНрд╡рдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП, Intlayer Compiler рдмрд┐рд▓реНрдб рд╕рдордп рдкрд░ рдпрд╣реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ рдкрд░рд┐рд╡рд░реНрддрди рдкрд░ рдХреЛрдб рд╕реНрдХреИрди рдХрд░рддрд╛ рд╣реИ, рд╢рдмреНрджрдХреЛрд╢ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдФрд░ HMR рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдХ рдХрд░рддрд╛ рд╣реИред

    рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЪрд╛рд▓реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рджреЛ рд╕реАрдорд╛рдПрдВ рдЬрд╛рдирдиреЗ рдпреЛрдЧреНрдп рд╣реИрдВред рдпрд╣ рд╕реНрдерд┐рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рджреНрд╡рд╛рд░рд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗрд╡рд▓ рд░рдирдЯрд╛рдЗрдо рдкрд░ рдореМрдЬреВрдж рд╣реЛрддреА рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ API рддреНрд░реБрдЯрд┐ рдХреЛрдб рдпрд╛ CMS рдлрд╝реАрд▓реНрдб, рд╡реЗ рдкрд╣реБрдВрдЪ рд╕реЗ рдмрд╛рд╣рд░ рд░рд╣рддреА рд╣реИрдВред рдФрд░ рдЗрд╕реЗ className="active" рдпрд╛ рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдЬреИрд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдЬрд┐рдХ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рдордиреЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдЯреЗрдХреНрд╕реНрдЯ рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝реЗ рдХреЛрдбрдмреЗрд╕ рдореЗрдВ рдХреБрдЫ рдПрдиреЛрдЯреЗрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред extract command рдЖрдкрдХреЛ рд▓реВрдк рдореЗрдВ рд░рдЦрдХрд░ рджреЛрдиреЛрдВ рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИред

    рдкрд╛рдБрдЪ рдЙрдкрдХрд░рдг, рд╕рднреА рд╡реИрдХрд▓реНрдкрд┐рдХ:

    • VS Code extension: useIntlayer рдХреБрдВрдЬреА рд╕реЗ рдЙрд╕реЗ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реА рд╕рд╛рдордЧреНрд░реА рдлрд╝рд╛рдЗрд▓ рдкрд░ рдЬрд╛рдПрдВ, рдШрдЯрдХреЛрдВ рд╕реЗ рд╕рд╛рдордЧреНрд░реА рдирд┐рдХрд╛рд▓реЗрдВ, рдФрд░ рдХрдорд╛рдВрдб рдкреИрд▓реЗрдЯ рдпрд╛ Intlayer рдЯреИрдм рд╕реЗ build, fill, test, push рдФрд░ pull рдЪрд▓рд╛рдПрдВред
    • LSP server: LSP рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рд╕рдВрдкрд╛рджрдХ рдореЗрдВ рд╕рдорд╛рди рд╕реБрд╡рд┐рдзрд╛, рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд░ рдЬрд╛рдПрдВ, рдЕрдиреБрд╡рд╛рджрд┐рдд рдорд╛рди рдХрд╛ рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рджреЗрдЦреЗрдВ, рдФрд░ рдХреБрдВрдЬреА рдкреВрд░реНрдгрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред i18next, react-i18next, next-intl рдФрд░ use-intl рдХреЙрд▓ рдХрд╛ рднреА рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред
    • MCP server: Cursor, VS Code, Claude Desktop, Claude Code рдФрд░ ChatGPT рдХреЗ рд▓рд┐рдП Intlayer рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдФрд░ CLI рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
    • Agent skills: рдХреЗрдВрджреНрд░рд┐рдд рдХреМрд╢рд▓ рдЬреИрд╕реЗ intlayer-config, intlayer-cli рдФрд░ intlayer-contentред
    • ESLint plugin: no-raw-text рдирд┐рдпрдо рд╣рд╛рд░реНрдбрдХреЛрдбреЗрдб рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИред