Author:
    Creation:2025-03-25Last update:2026-08-25

    Intlayer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Solid.js рдХреЗ рд╕рд╛рде рдЕрдкрдиреА Tanstack Start рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ | рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг (i18n)

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

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

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

    рд░рд┐рдПрдХреНрдЯ-рдЖрдИ18рдиреЗрдХреНрд╕реНрдЯ рдпрд╛ рдЖрдИ18рдиреЗрдХреНрд╕реНрдЯ рдЬреИрд╕реЗ рдореБрдЦреНрдп рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ, рдЗрдВрдЯрд▓реЗрдпрд░ рдПрдХ рдРрд╕рд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рдПрдХреАрдХреГрдд рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИ рдЬреИрд╕реЗ:

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

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

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

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

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

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

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

    Tanstack Start рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ Intlayer рд╕реЗрдЯрдЕрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреЗрдк-рдмрд╛рдп-рд╕реНрдЯреЗрдк рдЧрд╛рдЗрдб

    www.youtube.com
    ide.intlayer.org
    intlayer-tanstack-start-solid.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 solid-intlayer
      npm install vite-intlayer --save-dev
      
      • intlayer

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

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

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

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

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

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

      bash
      .
      тФЬтФАтФА src
      тФВ   тФЬтФАтФА components
      тФВ   тФВ   тФЬтФАтФА Header.content.ts
      тФВ   тФВ   тФЬтФАтФА Header.tsx
      тФВ   тФВ   тФЬтФАтФА LocaleSwitcher.content.ts
      тФВ   тФВ   тФЬтФАтФА LocaleSwitcher.tsx
      тФВ   тФВ   тФФтФАтФА LocalizedLink.tsx
      тФВ   тФЬтФАтФА 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 { intlayer } from "vite-intlayer";
      import { defineConfig } from "vite";
      import { devtools } from "@tanstack/devtools-vite";
      import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
      import solidPlugin from "vite-plugin-solid";
      
      export default defineConfig({
        plugins: [
          devtools(),
          tanstackStart({
            router: {
              routeFileIgnorePattern:
                ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5|md|mdx|yaml|yml)$",
            },
          }),
          solidPlugin({ ssr: true }),
          intlayer({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
        ],
      });
      
      intlayer() Vite рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ Intlayer рдХреЛ Vite рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рд╛рдордЧреНрд░реА рдШреЛрд╖рдгрд╛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдХрд╛рд╕ рдореЛрдб рдореЗрдВ рдЙрдирдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИред рдпрд╣ Vite рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рднреАрддрд░ Intlayer рд╡рд╛рддрд╛рд╡рд░рдг рдЪрд░ (environment variables) рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдУрд╡рд░рд╣реЗрдб рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдирд╛рдо (aliases) рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
    5. рд░реВрдЯ рд▓реЗрдЖрдЙрдЯ рдмрдирд╛рдПрдВ

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

      src/routes/__root.tsx
      import {
        HeadContent,
        Scripts,
        createRootRouteWithContext,
        getRouteApi,
      } from "@tanstack/solid-router";
      import { HydrationScript } from "solid-js/web";
      import { Suspense, type ParentComponent } from "solid-js";
      import { IntlayerProvider } from "solid-intlayer";
      import { defaultLocale, getHTMLTextDir } from "intlayer";
      
      const localeRoute = getRouteApi("/{-$locale}");
      
      export const Route = createRootRouteWithContext()({
        shellComponent: RootComponent,
      });
      
      const RootComponent: ParentComponent = (props) => {
        const params = localeRoute.useParams();
        const locale = params()?.locale ?? defaultLocale;
      
        return (
          <html dir={getHTMLTextDir(locale)} lang={locale}>
            <head>
              <HydrationScript />
              <HeadContent />
            </head>
            <body>
              <IntlayerProvider locale={locale}>
                <Suspense>{props.children}</Suspense>
              </IntlayerProvider>
              <Scripts />
            </body>
          </html>
        );
      };
      
    6. рд▓реЛрдХреЗрд▓ рд▓реЗрдЖрдЙрдЯ рдмрдирд╛рдПрдВ

      рдПрдХ рд▓реЗрдЖрдЙрдЯ рдмрдирд╛рдПрдВ рдЬреЛ рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ рдФрд░ рд╕рддреНрдпрд╛рдкрди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд▓реЗрдЖрдЙрдЯ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рдХреЗрд╡рд▓ рд╡реИрдз рд▓реЛрдХреЗрд▓ рд╣реА рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрдВред

      рдпрджрд┐ рдЖрдкрдХреЛ рд░реВрдЯ рд╕реНрддрд░ рдкрд░ рд▓реЛрдХреЗрд▓ рдЙрдкрд╕рд░реНрдЧ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рдЪрд░рдг рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИред
      src/routes/{-$locale}/route.tsx
      import { createFileRoute, Outlet, redirect } from "@tanstack/solid-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 },
              replace: true,
            });
          }
        },
        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 ejemplo 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/LocalizedLink.tsx
      import { Link, type LinkProps } from "@tanstack/solid-router";
      import { getPrefix } from "intlayer";
      import { useLocale } from "solid-intlayer";
      import type { JSX } from "solid-js";
      
      export const LOCALE_ROUTE = "{-$locale}" as const;
      
      export type RemoveLocaleParam<TVal> = TVal extends string
        ? RemoveLocaleFromString<TVal>
        : TVal;
      
      export type To = RemoveLocaleParam<LinkProps["to"]>;
      
      type CollapseDoubleSlashes<TString extends string> =
        TString extends `${infer THead}//${infer TTail}`
          ? CollapseDoubleSlashes<`${THead}/${TTail}`>
          : TString;
      
      export type LocalizedLinkProps = Omit<LinkProps, "to"> & {
        to?: To;
      } & JSX.AnchorHTMLAttributes<HTMLAnchorElement>;
      
      type RemoveAll<
        TString extends string,
        TSub extends string,
      > = TString extends `${infer THead}${TSub}${infer TTail}`
        ? RemoveAll<`${THead}${TTail}`, TSub>
        : TString;
      
      type RemoveLocaleFromString<TString extends string> = CollapseDoubleSlashes<
        RemoveAll<TString, typeof LOCALE_ROUTE>
      >;
      
      export const LocalizedLink = (props: LocalizedLinkProps) => {
        const { locale } = useLocale();
      
        return (
          <Link
            {...props}
            params={{
              locale: getPrefix(locale()).localePrefix,
              ...(typeof props.params === "object" ? props.params : {}),
            }}
            to={`/${LOCALE_ROUTE}${props.to ?? ""}` as LinkProps["to"]}
          />
        );
      };
      

      рдпрд╣ рдШрдЯрдХ рджреЛ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреА рдкреВрд░реНрддрд┐ рдХрд░рддрд╛ рд╣реИ:

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

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

      src/hooks/useLocalizedNavigate.tsx
      import { useNavigate } from "@tanstack/solid-router";
      import { getLocalizedUrl } from "intlayer";
      import { useLocale } from "solid-intlayer";
      
      export const useLocalizedNavigate = () => {
        const navigate = useNavigate();
        const { locale } = useLocale();
      
        const localizedNavigate = (to: string) => {
          const localizedTo = getLocalizedUrl(to, locale());
          return navigate({ to: localizedTo });
        };
      
        return localizedNavigate;
      };
      
    9. рдЕрдкрдиреЗ рдкреЗрдЬреЛрдВ рдореЗрдВ Intlayer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

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

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

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

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/solid-router";
      import { useIntlayer } from "solid-intlayer";
      import { LocalizedLink } from "@/components/LocalizedLink";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
      });
      
      function RouteComponent() {
        const content = useIntlayer("index-page");
      
        return (
          <main>
            <h1>{content.heroTitle}</h1>
            <p>{content.heroDesc}</p>
            <div>
              <LocalizedLink to="/">{content.navHome}</LocalizedLink>
              <LocalizedLink to="/about">{content.navAbout}</LocalizedLink>
            </div>
          </main>
        );
      }
      
      html
      <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)}" />
      

      In Solid, useIntlayer returns reactive content (e.g., content). You can access its properties directly.

      useIntlayer рд╣реБрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рджреЗрдЦреЗрдВред

    10. рд▓реЛрдХреЗрд▓ рд╕реНрд╡рд┐рдЪрд░ рдШрдЯрдХ рдмрдирд╛рдПрдВ

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

      src/components/LocaleSwitcher.tsx
      import { useLocation } from "@tanstack/solid-router";
      import { getLocaleName, getPathWithoutLocale, getPrefix } from "intlayer";
      import { For } from "solid-js";
      import { useIntlayer, useLocale } from "solid-intlayer";
      import { LocalizedLink, type To } from "./LocalizedLink";
      
      export const LocaleSwitcher = () => {
        const content = useIntlayer("locale-switcher");
        const location = useLocation();
      
        const { availableLocales, locale, setLocale } = useLocale();
      
        const pathWithoutLocale = () => getPathWithoutLocale(location().pathname);
      
        return (
          <div class="flex flex-row gap-2">
            <For each={availableLocales}>
              {(localeEl) => (
                <LocalizedLink
                  aria-current={localeEl === locale() ? "page" : undefined}
                  onClick={() => setLocale(localeEl)}
                  params={{ locale: getPrefix(localeEl).localePrefix }}
                  to={pathWithoutLocale() as To}
                >
                  {getLocaleName(localeEl)}
                </LocalizedLink>
              )}
            </For>
          </div>
        );
      };
      
      export default LocaleSwitcher;
      

      Solid рдореЗрдВ, useLocale рд╕реЗ locale рдПрдХ рд╕рд┐рдЧреНрдирд▓ рдПрдХреНрд╕реЗрд╕реЙрд░ рд╣реИред рдЗрд╕рдХреЗ рд╡рд░реНрддрдорд╛рди рдорд╛рди рдХреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд░реВрдк рд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП locale() (рдХреЛрд╖реНрдардХ рдХреЗ рд╕рд╛рде) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

      useLocale рд╣реБрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рджреЗрдЦреЗрдВред

    11. HTML рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди

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

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

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

      рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЙрддреНрдкрд╛рджрди рдореЗрдВ intlayerProxy рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ vite-intlayer рдкреИрдХреЗрдЬ рдХреЛ devDependencies рд╕реЗ dependencies рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред
      Intlayer v9 рдХреЗ рдмрд╛рдж рд╕реЗ, intlayerProxy() рдХреЛ рд╕реАрдзреЗ intlayer() рдкреНрд▓рдЧрдЗрди рдореЗрдВ рдмрдВрдбрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ routing.enableProxy рд╡рд┐рдХрд▓реНрдк (true рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕реЗ рдЕрд▓рдЧ рд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЕрдм рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдкрд┐рдЫрдбрд╝реЗ рд╕рдВрдЧрддрддрд╛ рдХреЗ рд▓рд┐рдП рдФрд░ рдЙрди рд╕реЗрдЯрдЕрдк рдХреЗ рд▓рд┐рдП рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдкреНрд▓рдЧрдЗрди рдСрд░реНрдбрд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред routing.enableProxy: false рд╕реЗрдЯ рдХрд░реЗрдВ рдСрдкреНрдЯ рдЖрдЙрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред v9 рд░рд┐рд▓реАрдЬрд╝ рдиреЛрдЯреНрд╕ рджреЗрдЦреЗрдВред
      vite.config.ts
      import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
      import solid from "vite-plugin-solid";
      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)$",
            },
          }),
          solid(),
        ],
      });
      
    13. рдЕрдкрдиреЗ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЛ рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХреГрдд рдХрд░реЗрдВ

      getIntlayer рдорд░реНрдЬ рдХреА рдЧрдИ рдбрд┐рдХреНрд╢рдирд░реА (рдЬрд┐рд╕рдореЗрдВ рд╕рднреА рдШреЛрд╖рд┐рдд рд▓реЛрдХреЗрд▓ рд╣реЛрддреЗ рд╣реИрдВ) рдХреЗ рд╡рд┐рд░реБрджреНрдз рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рд╣рд▓ рд╣реЛрддрд╛ рд╣реИред head рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░рд╣рддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рднреА await рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛, рд▓реЗрдХрд┐рди рдкреВрд░реА рдмрд╣реБрднрд╛рд╖реА рдбрд┐рдХреНрд╢рдирд░реА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рднреЗрдЬреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд░реВрдЯ рдЪрдВрдХ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИред

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/solid-router";
      import {
        defaultLocale,
        getIntlayer,
        getLocalizedUrl,
        localeMap,
      } from "intlayer";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
        head: ({ params }) => {
          const { locale = defaultLocale } = params;
          const path = "/"; // The path for this route
      
          const metaContent = getIntlayer("app", locale);
      
          return {
            links: [
              // Canonical link: Points to the current localized page
              { rel: "canonical", href: getLocalizedUrl(path, locale) },
      
              // Hreflang: Tell Google about all localized versions
              ...localeMap(({ locale: mapLocale }) => ({
                rel: "alternate",
                hrefLang: mapLocale,
                href: getLocalizedUrl(path, mapLocale),
              })),
      
              // x-default: For users in unmatched languages
              // Define the default fallback locale (usually your primary language)
              {
                rel: "alternate",
                hrefLang: "x-default",
                href: getLocalizedUrl(path, defaultLocale),
              },
            ],
            meta: [
              { title: metaContent.title },
              { name: "description", content: metaContent.meta.description },
            ],
          };
        },
      });
      

      рдЫреЛрдЯреА рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдбрд┐рдХреНрд╢рдирд░реА, рдХреБрдЫ рд╣реА рд▓реЛрдХреЗрд▓, рдпрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрддред

      getIntlayerAsync (v9.4 рд╕реЗ рдЙрдкрд▓рдмреНрдз) getIntlayer рдХреА рддрд░рд╣ рд╣реА рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд┐рд▓реНрдб рдкреНрд▓рдЧрдЗрди рдЗрд╕реЗ рдорд░реНрдЬ рдХреА рдЧрдИ рдбрд┐рдХреНрд╢рдирд░реА рдХреЗ рдмрдЬрд╛рдп .intlayer/dynamic_dictionaries/ рдореЗрдВ рдореМрдЬреВрдж рдкреНрд░рддрд┐-рд▓реЛрдХреЗрд▓ рдЪрдВрдХ рдХреА рдУрд░ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдкреЗрдЬ рдХреЗрд╡рд▓ рдЙрд╕реА рд▓реЛрдХреЗрд▓ рдХреЛ рднреЗрдЬрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╡рд╣ рд░реЗрдВрдбрд░ рдХрд░рддрд╛ рд╣реИред рдЪреВрдБрдХрд┐ рд╡рд╣ рдЪрдВрдХ рдорд╛рдБрдЧ рдкрд░ рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИ, head async рдмрди рдЬрд╛рддрд╛ рд╣реИ:

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/solid-router";
      import {
        defaultLocale,
        getIntlayerAsync,
        getLocalizedUrl,
        localeMap,
      } from "intlayer";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
        head: async ({ params }) => {
          const { locale = defaultLocale } = params;
          const path = "/"; // The path for this route
      
          const metaContent = await getIntlayerAsync("app", locale);
      
          return {
            links: [
              // Canonical link: Points to the current localized page
              { rel: "canonical", href: getLocalizedUrl(path, locale) },
      
              // Hreflang: Tell Google about all localized versions
              ...localeMap(({ locale: mapLocale }) => ({
                rel: "alternate",
                hrefLang: mapLocale,
                href: getLocalizedUrl(path, mapLocale),
              })),
      
              // x-default: For users in unmatched languages
              // Define the default fallback locale (usually your primary language)
              {
                rel: "alternate",
                hrefLang: "x-default",
                href: getLocalizedUrl(path, defaultLocale),
              },
            ],
            meta: [
              { title: metaContent.title },
              { name: "description", content: metaContent.meta.description },
            ],
          };
        },
      });
      
      рдпрджрд┐ рдХреЛрдИ head рдХрдИ рдбрд┐рдХреНрд╢рдирд░реА рдкрдврд╝рддрд╛ рд╣реИ, рддреЛ рдЙрдиреНрд╣реЗрдВ Promise.all рд╕реЗ рд╣рд▓ рдХрд░реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рд░ getIntlayerAsync рдХреЛ рдЕрд▓рдЧ рдкрдВрдХреНрддрд┐ рдореЗрдВ await рдХрд░рдиреЗ рд╕реЗ рдЕрдиреБрд░реЛрдз рд╕рдорд╛рдирд╛рдВрддрд░ рдЪрд▓рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдПрдХ-рджреВрд╕рд░реЗ рд╕реЗ рдЬреБрдбрд╝рдХрд░ рдХреНрд░рдордмрджреНрдз рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред

      рд╕рдордЭреМрддрд╛ рдпрд╣ рд╣реИ: рдбрд╛рдпрдирд╛рдорд┐рдХ import рддрдм рд╣рд▓ рд╣реЛрддрд╛ рд╣реИ рдЬрдм head рдЪрд▓ рд░рд╣рд╛ рд╣реЛрддрд╛ рд╣реИ, рдпрд╛рдиреА рдбреЙрдХреНрдпреВрдореЗрдВрдЯ рд░реЗрдВрдбрд░ рдХреЗ рдХреНрд░рд┐рдЯрд┐рдХрд▓ рдкрд╛рде рдкрд░ред рдХреЛрд▓реНрдб рд░реВрдЯ рдкрд░ рдЗрд╕рд╕реЗ head рдХреБрдЫ рдорд┐рд▓реАрд╕реЗрдХрдВрдб рджреЗрд░ рд╕реЗ рддреИрдпрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ LCP рдереЛрдбрд╝рд╛ рдмрд┐рдЧрдбрд╝ рд╕рдХрддрд╛ рд╣реИред

      рдбрд┐рдХреНрд╢рдирд░реА рдХреЛ рд░реВрдЯ рдХреЗ loader рдореЗрдВ рд╣рд▓ рдХрд░реЗрдВ рдФрд░ head рдореЗрдВ loaderData рд╕реЗ рд╡рд╛рдкрд╕ рдкрдврд╝реЗрдВред рдореИрдЪ рд╣реБрдП рд░реВрдЯ рдХреЗ рд▓реЛрдбрд░ рд╕рдорд╛рдирд╛рдВрддрд░ рдЪрд▓рддреЗ рд╣реИрдВ, рдФрд░ staleTime: Infinity TanStack Router рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рдХрднреА рдмрд╛рд╕реА рдирд╣реАрдВ рд╣реЛрддрд╛, рдЗрд╕рд▓рд┐рдП рдкреНрд░рддрд┐-рд▓реЛрдХреЗрд▓ рдЪрдВрдХ рдПрдХ рд╣реА рдмрд╛рд░ рд╣рд▓ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд░рд╛рдЙрдЯрд░ рдХреИрд╢ рд╕реЗ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ head рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдмрдирд╛ рд░рд╣рддрд╛ рд╣реИред

      src/routes/{-$locale}/index.tsx
      import { createFileRoute } from "@tanstack/solid-router";
      import {
        defaultLocale,
        getIntlayerAsync,
        getLocalizedUrl,
        localeMap,
      } from "intlayer";
      
      export const Route = createFileRoute("/{-$locale}/")({
        component: RouteComponent,
        // Resolved in parallel with the other matched routes, off the head critical path
        loader: async ({ params }) => {
          const { locale = defaultLocale } = params;
      
          return { metaContent: await getIntlayerAsync("app", locale) };
        },
        // The dictionary never changes for a given locale: resolve the chunk once
        staleTime: Infinity,
        head: ({ params, loaderData }) => {
          const { locale = defaultLocale } = params;
          const path = "/"; // The path for this route
      
          return {
            links: [
              // Canonical link: Points to the current localized page
              { rel: "canonical", href: getLocalizedUrl(path, locale) },
      
              // Hreflang: Tell Google about all localized versions
              ...localeMap(({ locale: mapLocale }) => ({
                rel: "alternate",
                hrefLang: mapLocale,
                href: getLocalizedUrl(path, mapLocale),
              })),
      
              // x-default: For users in unmatched languages
              // Define the default fallback locale (usually your primary language)
              {
                rel: "alternate",
                hrefLang: "x-default",
                href: getLocalizedUrl(path, defaultLocale),
              },
            ],
            meta: [
              { title: loaderData?.metaContent.title },
              {
                name: "description",
                content: loaderData?.metaContent.meta.description,
              },
            ],
          };
        },
      });
      
      рд▓реЛрдбрд░ рдкреВрд░рд╛ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рднреА head рдХреЙрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП loaderData рдХрд╛ рдЯрд╛рдЗрдк рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ undefined рд╣реИред рдСрдкреНрд╢рдирд▓ рдЪреЗрдирд┐рдВрдЧ рдмрдирд╛рдП рд░рдЦреЗрдВ, рдпрд╛ рдХреЛрдИ рдлрд╝реЙрд▓рдмреИрдХ рдЯрд╛рдЗрдЯрд▓ рд▓реМрдЯрд╛рдПрдБред

      рдЖрдк рдкреНрд░рддрд┐-рд▓реЛрдХреЗрд▓ рдЪрдВрдХ рдХрд╛ рд▓рд╛рдн рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВ, рдмрд┐рдирд╛ рдЙрд╕рдХреА рд▓рд╛рдЧрдд head рдХреЗ рдХреНрд░рд┐рдЯрд┐рдХрд▓ рдкрд╛рде рдкрд░ рдЪреБрдХрд╛рдПред рдХреАрдордд рдбреЗрд╡рд▓рдкрд░ рдЕрдиреБрднрд╡ рдХреА рд╣реИ: рдХрдВрдЯреЗрдВрдЯ рдХреЛ рд▓реЛрдбрд░ рд╕реЗ head рддрдХ loaderData рдХреЗ рдЬрд╝рд░рд┐рдП рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд╣реБрдБрдЪрд╛рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИред

      рдХреМрди-рд╕рд╛ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдЪреБрдиреЗрдВ?

      рд╕реНрдЯреИрдЯрд┐рдХ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рдирдбрд╛рдпрдирд╛рдорд┐рдХ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рдирдХреИрд╢реНрдб рдбрд╛рдпрдирд╛рдорд┐рдХ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди
      APIgetIntlayergetIntlayerAsync (v9.4+)loader рдореЗрдВ getIntlayerAsync (v9.4+)
      head рд╕рд┐рдЧреНрдиреЗрдЪрд░рд╕рд┐рдВрдХреНрд░реЛрдирд╕asyncрд╕рд┐рдВрдХреНрд░реЛрдирд╕, loaderData рдкрдврд╝рддрд╛ рд╣реИ
      рднреЗрдЬреЗ рдЧрдП рд▓реЛрдХреЗрд▓рд╕рднреА рдШреЛрд╖рд┐рдд рд▓реЛрдХреЗрд▓рдХреЗрд╡рд▓ рдЕрдиреБрд░реЛрдзрд┐рдд рд▓реЛрдХреЗрд▓рдХреЗрд╡рд▓ рдЕрдиреБрд░реЛрдзрд┐рдд рд▓реЛрдХреЗрд▓
      рдХреНрд▓рд╛рдЗрдВрдЯ рдиреЗрд╡рд┐рдЧреЗрд╢рдирд╣рд▓ рдХрд░рдиреЗ рдХреЛ рдХреБрдЫ рдирд╣реАрдВрд╣рд░ рдореИрдЪ рдкрд░ рджреЛрдмрд╛рд░рд╛ рдЪрд▓рддрд╛ рд╣реИрд░рд╛рдЙрдЯрд░ рдХреИрд╢ рд╕реЗ рдорд┐рд▓рддрд╛ рд╣реИ
      рдбреЗрд╡рд▓рдкрд░ рдЕрдиреБрднрд╡рд╕рдмрд╕реЗ рд╕рд░рд▓рдПрдХ awaitрдХрдВрдЯреЗрдВрдЯ loaderData рд╕реЗ рдкрд╛рд╕ рд╣реЛрддрд╛ рд╣реИ
    14. рдЕрдкрдиреЗ рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд▓реЛрдХреЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

      рдЖрдк рдЕрдкрдиреЗ рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпреЛрдВ рдпрд╛ API рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЗ рднреАрддрд░ рд╕реЗ рд╡рд░реНрддрдорд╛рди рд▓реЛрдХреЗрд▓ рддрдХ рдкрд╣реБрдБрдЪрдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк intlayer рд╕реЗ getLocale рд╣реЗрд▓реНрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

      TanStack Start рдХреЗ рд╕рд░реНрд╡рд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдБ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

      src/routes/{-$locale}/index.tsx
      import { createServerFn } from "@tanstack/solid-start";
      import {
        getRequestHeader,
        getRequestHeaders,
      } from "@tanstack/solid-start/server";
      import { getCookie, getIntlayer, getLocale } from "intlayer";
      
      export const getLocaleServer = createServerFn().handler(async () => {
        const locale = await getLocale({
          // рдЕрдиреБрд░реЛрдз рд╕реЗ рдХреБрдХреА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ: 'INTLAYER_LOCALE')
          getCookie: (name) => {
            const cookieString = getRequestHeader("cookie");
      
            return getCookie(name, cookieString);
          },
          // рдЕрдиреБрд░реЛрдз рд╕реЗ рд╣реЗрдбрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ: 'x-intlayer-locale')
          // Accept-Language рдмрд╛рддрдЪреАрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝реЙрд▓рдмреИрдХ
          getHeader: (name) => getRequestHeader(name),
        });
      
        // some content retrieved with getIntlayer()
        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/solid-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/solid-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/solid-router";
      
      import { NotFoundComponent } from "./404";
      
      // $ (рд╕реНрдкреНрд▓реИрдЯ/рдХреИрдЪ-рдСрд▓) рд░реВрдЯ рдХрд┐рд╕реА рднреА рдкрде рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬреЛ рдЕрдиреНрдп рд░реВрдЯ рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ
      // рдЙрджрд╛: /en/some/deeply/nested/invalid/path
      // рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдХреЗрд▓ рдХреЗ рднреАрддрд░ рд╕рднреА рдЧреИрд░-рдорд┐рд▓рд╛рди рдкрде 404 рдкреЗрдЬ рджрд┐рдЦрд╛рдПрдВ
      // рдЗрд╕рдХреЗ рдмрд┐рдирд╛, рдЧрд╣рд░реЗ рдЧреИрд░-рдорд┐рд▓рд╛рди рдкрде рдПрдХ рдЦрд╛рд▓реА рдкреЗрдЬ рдпрд╛ рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ
      export const Route = createFileRoute("/{-$locale}/$")({
        component: NotFoundComponent,
      });
      
    16. рдЕрдкрдиреЗ рдШрдЯрдХреЛрдВ рд╕реЗ рд╕рд╛рдордЧреНрд░реА рдирд┐рдХрд╛рд▓реЗрдВ

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

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

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

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

      intlayer.config.ts
      import { type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        // ... рдЖрдкрдХреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рд╢реЗрд╖ рднрд╛рдЧ
        compiler: {
          /**
           * рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
           */
          enabled: true,
      
          /**
           * рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдкрде рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ
           */
          output: ({ fileName, extension }) => `./${fileName}${extension}`,
      
          /**
           * рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдШрдЯрдХреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рдж рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
           *
           * - рдпрджрд┐ `true` рд╣реИ, рддреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рдбрд┐рд╕реНрдХ рдкрд░ рдШрдЯрдХ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдЧрд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкрд░рд┐рд╡рд░реНрддрди рд╕реНрдерд╛рдпреА рд╣реЛрдЧрд╛, рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрдЧрд▓реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЫреЛрдбрд╝ рджреЗрдЧрд╛ред рдЗрд╕ рддрд░рд╣, рдХрдВрдкрд╛рдЗрд▓рд░ рдРрдк рдХреЛ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
           *
           * - рдпрджрд┐ `false` рд╣реИ, рддреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛрдб рдореЗрдВ `useIntlayer()` рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЛ рдХреЗрд╡рд▓ рдмрд┐рд▓реНрдб рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░реЗрдЧрд╛, рдЬрд┐рд╕рд╕реЗ рдореВрд▓ рдХреЛрдбрдмреЗрд╕ рдмрд░рдХрд░рд╛рд░ рд░рд╣реЗрдЧрд╛ред рдкрд░рд┐рд╡рд░реНрддрди рдХреЗрд╡рд▓ рдореЗрдореЛрд░реА рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
           */
          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 { intlayer, intlayerCompiler } from "vite-intlayer";
      import { defineConfig } from "vite";
      import { devtools } from "@tanstack/devtools-vite";
      import { tanstackStart } from "@tanstack/solid-start/plugin/vite";
      import solidPlugin from "vite-plugin-solid";
      
      export default defineConfig({
        plugins: [
          devtools(),
          tanstackStart({
            router: {
              routeFileIgnorePattern:
                ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5|md|mdx|yaml|yml)$",
            },
          }),
          solidPlugin({ ssr: true }),
          intlayer(),
          intlayerCompiler(), // Adds the compiler plugin
        ],
      });
      
      bash
      npm run build # рдпрд╛ npm run dev
      
    17. Pre-render & Generate Sitemap

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

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

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

      vite.config.ts
      import { localeMap, 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/solid-router";
      import { generateSitemap } from "intlayer";
      
      // рд╕рд╛рдЗрдЯ рдХрд╛ URL
      const SITE_URL = "http://localhost:3000";
      
      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: SITE_URL }
              );
      
              // XML рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд▓реМрдЯрд╛рдПрдВ
              return new Response(sitemap, {
                headers: { "Content-Type": "application/xml" },
              });
            },
          },
        },
      });
      
    18. TypeScript рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ

      Intlayer TypeScript рдХреЗ рд▓рд╛рднреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдЖрдкрдХреЗ рдХреЛрдбрдмреЗрд╕ рдХреЛ рдордЬрдмреВрдд рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдбреНрдпреВрд▓ рдСрдЧреНрдореЗрдВрдЯреЗрд╢рди (module augmentation) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

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

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

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

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

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

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

    VS Code рдПрдХреНрд╕рдЯреЗрдВрд╢рди

    Intlayer рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рд╡рд┐рдХрд╛рд╕ рдЕрдиреБрднрд╡ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЖрдзрд┐рдХрд╛рд░рд┐рдХ Intlayer VS Code рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

    VS Code Marketplace рд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ

    рдпрд╣ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:

    • рдЕрдиреБрд╡рд╛рдж рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдСрдЯреЛ-рдХрдореНрдкреНрд▓реАрд╢рдиред
    • рдЧреБрдо рдЕрдиреБрд╡рд╛рджреЛрдВ рдХреЗ рд▓рд┐рдП рд░реАрдпрд▓-рдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐ рдкрд╣рдЪрд╛рдиред
    • рдЕрдиреВрджрд┐рдд рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЗрдирд▓рд╛рдЗрди рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрдиред
    • рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдиреБрд╡рд╛рдж рдмрдирд╛рдиреЗ рдФрд░ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреНрд╡рд░рд┐рдд рдХрд╛рд░реНрдпред

    рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП, Intlayer VS Code рдПрдХреНрд╕рдЯреЗрдВрд╢рди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рджреЗрдЦреЗрдВред

    рдЖрдЧреЗ рдмрдврд╝рдирд╛

    рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рд╡рд┐рдЬреБрдЕрд▓ рдПрдбрд┐рдЯрд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ CMS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрд╛рд╣рд░реА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред

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

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

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

    • @solid-primitives/i18n: рд╕реАрдорд┐рдд SSR рд╕рдорд░реНрдерди рд╡рд╛рд▓рд╛ рд╕рд░рд▓ рд╢рдмреНрджрдХреЛрд╢ред
    • Intlayer: SSR рдФрд░ SSG рд╕рдорд░реНрдерди, Solid рд╕рд┐рдЧреНрдирд▓, рдмрд┐рд▓реНрдб рд╕рдордп рдЕрдиреБрдХреВрд▓рди, AI рдЕрдиреБрд╡рд╛рдж рдФрд░ рд╡рд┐рдЬрд╝реБрдЕрд▓ рдПрдбрд┐рдЯрд░ред

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

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

    рдХрд╛рдлреА рд╣рдж рддрдХ рд╣рд╛рдБред i18next рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЧрд╛рдЗрдб рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВред

    рд╣рд╛рдБред 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 рдирд┐рдпрдо рд╣рд╛рд░реНрдбрдХреЛрдбреЗрдб рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИред