ГоловнаПісочницяВітринаДодатокДокументаціяБлог
    • Englishанглійська
      EN
    • русскийросійська
      RU
    • 日本語японська
      JA
    • françaisфранцузька
      FR
    • 한국어корейська
      KO
    • 中文китайська
      ZH
    • españolіспанська
      ES
    • Deutschнімецька
      DE
    • العربيةарабська
      AR
    • italianoіталійська
      IT
    • British Englishанглійська (Велика Британія)
      EN-GB
    • portuguêsпортугальська
      PT
    • हिन्दीгінді
      HI
    • Türkçeтурецька
      TR
    • polskiпольська
      PL
    • Indonesiaіндонезійська
      ID
    • Tiếng Việtвʼєтнамська
      VI
    • українськаукраїнська
      UK
    /
    Фільтрувати документи за фреймворком
    Alt+←
    Чому Intlayer?
    Почати
    Концепція
    • Як працює Intlayer
    • Конфігурація
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • Візуальний редактор
    • CMS
    • Інтеграція CI/CD
    • ПерекладМножинаПерелікУмоваРідВставкаФайлВкладеністьMarkdownHTMLОтримання функції
    • Файл для кожної локалі
    • Компілятор
    • Автозаповнення
    • Тестування
    • Оптимізація пакета
    Середовище
    • Next.js 14 та App Router
      Next.js 15
      Next.js без locale URL
      Next.js та Page Router
      Compiler
    • Tanstack Start Solid
    • Astro та React
      Astro та Svelte
      Astro та Vue
      Astro та Solid
      Astro та Preact
      Astro та Lit
      Astro та Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt та Vue
    • Vite та Solid
    • SvelteKit
    • Vite та Preact
    • Vite та Vanilla JS
    • Vite та Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native та Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx та React
    Plugins
    • JSON
    • gettext (.po)
    Розширення VS Code
    Агент
    • Сервер MCP
    • Навички агента
    Релізи
    • v8
    • v7
    • v6
    Бенчмарк
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    Блог
    Задати питання
    1. Documentation
    2. Середовище
    3. Tanstack Start
    4. Solid
    Дата створення:2025-03-25Останнє оновлення:2026-05-06
    Переглянути шаблон додатку на GitHub

    На цій сторінці доступний шаблон додатку.

    Переглянути демонстраційний додаток

    Ця сторінка веде на живу демонстрацію шаблону.

    Переглянути відеоурок

    На цій сторінці доступний відеоурок.

    Надішліть цей документ вашому улюбленому AI-асистенту
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту

    Історія версій

    1. "Оновлення використання API useIntlayer у Solid для прямого доступу до властивостей"
      v8.9.004.05.2026
    2. "Додано для Tanstack Start Solid.js"
      v8.5.125.03.2026

    Вміст цієї сторінки перекладено за допомогою штучного інтелекту.

    Переглянути останню версію оригінального вмісту англійською
    Редагувати цей документ

    Якщо у вас є ідея щодо покращення цієї документації, будь ласка, долучіться, надіславши pull request на GitHub.

    Посилання на документацію на GitHub
    Копіювати

    Скопіювати документацію у форматі Markdown в буфер обміну

    Перекладіть свій вебсайт Tanstack Start + Solid.js за допомогою Intlayer | Інтернаціоналізація (i18n)

    Зміст

    Цей посібник демонструє, як інтегрувати Intlayer для безперешкодної інтернаціоналізації в проектах Tanstack Start із Solid.js, маршрутизацією з урахуванням локалі, підтримкою TypeScript та сучасними практиками розробки.

    Що таке Intlayer?

    Intlayer - це інноваційна бібліотека інтернаціоналізації (i18n) з відкритим кодом, розроблена для спрощення підтримки багатьох мов у сучасних веб-додатках.

    З Intlayer ви можете:

    • Легко керувати перекладами за допомогою декларативних словників на рівні компонентів.
    • Динамічно локалізувати метадані, маршрути та вміст.
    • Забезпечити підтримку TypeScript за допомогою автоматично згенерованих типів, покращуючи автодоповнення та виявлення помилок.
    • Користуватися розширеними функціями, такими як динамічне визначення та перемикання локалі.
    • Увімкнути маршрутизацію з урахуванням локалі за допомогою файлової системи маршрутизації Tanstack Start.

    Покроковий посібник із налаштування Intlayer у додатку Tanstack Start

    www.youtube.com
    ide.intlayer.org
    intlayer-tanstack-start-solid.vercel.app

    Перегляньте Шаблон додатка на GitHub.

    Крок 1: Створення проекту

    Спочатку створіть новий проект TanStack Start, дотримуючись посібника Початок нового проекту на вебсайті TanStack Start.

    Крок 2: Встановлення пакетів Intlayer

    Встановіть необхідні пакети за допомогою бажаного менеджера пакетів:

    bash
    Копіювати код

    Скопіюйте код у буфер обміну

    npm install intlayer solid-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer

      Основний пакет, який надає інструменти інтернаціоналізації для керування конфігурацією, перекладу, декларування вмісту, транспіляції та команд CLI.

    • solid-intlayer Пакет, що інтегрує Intlayer у додаток Solid. Він надає контекстні провайдери та хуки для інтернаціоналізації Solid.

    • vite-intlayer Включає плагін Vite для інтеграції Intlayer з бандлером Vite, а також проміжне програмне забезпечення (middleware) для визначення бажаної локалі користувача, керування файлами cookie та обробки перенаправлення URL-адрес.

    Крок 3: Конфігурація вашого проекту

    Створіть файл конфігурації, щоб налаштувати мови вашого додатка:

    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-адреси, перенаправлення через middleware, назви файлів cookie, розташування та розширення ваших декларацій вмісту, вимкнути логи Intlayer у консолі тощо. Повний список доступних параметрів див. у документації з конфігурації.

    Крок 4: Інтеграція Intlayer у вашу конфігурацію Vite

    Додайте плагін 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)$",      },    }),    solidPlugin({ ssr: true }),    intlayer(),  ],});
    Плагін Vite intlayer() використовується для інтеграції Intlayer з Vite. Він забезпечує збірку файлів декларації вмісту та моніторить їх у режимі розробки. Він визначає змінні середовища Intlayer у додатку Vite. Крім того, він надає псевдоніми (aliases) для зменшення накладних витрат на продуктивність.

    Крок 5: Створення кореневого макета (Root Layout)

    Налаштуйте свій кореневий макет для підтримки інтернаціоналізації, використовуючи useParams для визначення поточної локалі та встановлюючи атрибути lang і dir на тегу html.

    src/routes/__root.tsx
    Копіювати код

    Скопіюйте код у буфер обміну

    import {  HeadContent,  Scripts,  createRootRouteWithContext,} 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";import { Route as LocaleRoute } from "./{-$locale}/route";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}).
    Докладнішу інформацію див. у документації з декларування вмісту.

    Крок 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"]}    />  );};

    Цей компонент виконує дві функції:

    • Видалення непотрібного префікса {-$locale} з URL.
    • Вставлення параметра локалі в 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 на ваших сторінках

    Отримуйте доступ до своїх словників вмісту в усьому додатку:

    Локалізована домашня сторінка

    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>  );}
    Якщо ви хочете використовувати свій вміст в атрибуті типу string, наприклад alt, title, href, aria-label тощо, ви повинні викликати значення функції, наприклад:
    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 locale з useLocale є signal accessor. Використовуйте locale() (з дужками), щоб реактивно читати його поточне значення.

    Щоб дізнатися більше про хук useLocale, зверніться до документації.

    Крок 11: Керування атрибутами HTML

    Як було показано на кроці 5, ви можете керувати атрибутами lang і dir тегу html, використовуючи useParams у вашому кореневому компоненті. Це гарантує, що правильні атрибути встановлено як на сервері, так і на клієнті.

    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: Додавання Middleware (опціонально)

    Ви також можете використовувати intlayerProxy, щоб додати маршрутизацію на стороні сервера до вашого додатка. Цей плагін автоматично визначатиме поточну локаль на основі URL-адреси та встановлюватиме відповідний файл cookie локалі. Якщо локаль не вказано, плагін визначить найбільш підходящу локаль на основі налаштувань мови браузера користувача. Якщо локаль не виявлено, він перенаправить на локаль за замовчуванням.

    Зверніть увагу, що для використання intlayerProxy у продакшні вам потрібно перенести пакет vite-intlayer з devDependencies до dependencies.
    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, intlayerProxy } from "vite-intlayer";export default defineConfig({  plugins: [    intlayerProxy(), // Проксі слід розміщувати перед сервером, якщо ви використовуєте Nitro    nitro(),    intlayer(),    tanstackStart({      router: {        routeFileIgnorePattern:          ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5)$",      },    }),    solid(),  ],});

    Крок 13: Інтернаціоналізація ваших метаданих (опціонально)

    Ви також можете використовувати функцію getIntlayer, щоб отримати доступ до ваших словників вмісту в завантажувачі head для метаданих з урахуванням локалі:

    src/routes/{-$locale}/index.tsx
    Копіювати код

    Скопіюйте код у буфер обміну

    import { createFileRoute } from "@tanstack/solid-router";import { getIntlayer } from "intlayer";export const Route = createFileRoute("/{-$locale}/")({  component: RouteComponent,  head: ({ params }) => {    const { locale } = 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 },      ],    };  },});

    Крок 14: Отримання локалі у ваших діях на сервері (опціонально)

    Ви можете захотіти отримати доступ до поточної локалі з ваших серверних дій (server actions) або кінцевих точок API. Ви можете зробити це за допомогою допоміжної функції getLocale з intlayer.

    Ось приклад з використанням серверних функцій 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),  });  // Отримати якийсь вміст за допомогою getIntlayer()  const content = getIntlayer("app", locale);  return { locale, content };});

    Крок 15: Керування сторінками "не знайдено" (404) (опціонально)

    Коли користувач відвідує неіснуючу сторінку, ви можете відобразити власну сторінку "не знайдено", і префікс локалі може вплинути на те, як ця сторінка запускається.

    Розуміння обробки 404 в TanStack Router з префіксами локалі

    У TanStack Router обробка сторінок 404 з локалізованими маршрутами вимагає багаторівневого підходу:

    1. Спеціальний маршрут 404: Окремий маршрут для відображення інтерфейсу 404
    2. Валідація на рівні маршруту: Перевіряє префікси локалі та перенаправляє недійсні на 404
    3. Catch-all маршрут: Захоплює будь-які шляхи, що не збігаються, всередині сегмента локалі
    src/routes/{-$locale}/404.tsx
    Копіювати код

    Скопіюйте код у буфер обміну

    import { createFileRoute } from "@tanstack/solid-router";// Це створює спеціальний маршрут /[locale]/404// Він використовується і як прямий маршрут, і як компонент в інших файлахexport const Route = createFileRoute("/{-$locale}/404")({  component: NotFoundComponent,});// Експортується окремо, щоб його можна було повторно використовувати в notFoundComponent та catch-all маршрутах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/неіснуюча-сторінка запускає це всередині макета /en  notFoundComponent: NotFoundComponent,});
    src/routes/{-$locale}/$.tsx
    Копіювати код

    Скопіюйте код у буфер обміну

    import { createFileRoute } from "@tanstack/solid-router";import { NotFoundComponent } from "./404";// Маршрут $ (splat/catch-all) збігається з будь-яким шляхом, що не збігається з іншими маршрутами// напр.: /en/якийсь/глибоко/вкладений/недійсний/шлях// Це гарантує, що ВСІ невідповідні шляхи всередині локалі показують сторінку 404// Без цього глибокі невідповідні шляхи могли б показувати порожню сторінку або помилкуexport const Route = createFileRoute("/{-$locale}/$")({  component: NotFoundComponent,});

    (Опціонально) Крок 16: Вилучення вмісту з ваших компонентів

    Якщо у вас є існуюча кодова база, трансформація тисяч файлів може зайняти багато часу.

    Щоб полегшити цей процес, Intlayer пропонує компілятор / екстрактор для трансформації ваших компонентів та вилучення вмісту.

    Щоб налаштувати його, ви можете додати розділ compiler у свій файл intlayer.config.ts:

    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

    Оновіть свій vite.config.ts, щоб включити плагін intlayerCompiler:

    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)$",     },   }),   solidPlugin({ ssr: true }),   intlayer(),   intlayerCompiler(), ],});
    bash
    Копіювати код

    Скопіюйте код у буфер обміну

    npm run build # Або rpm run dev

    Крок 17: Конфігурація TypeScript (опціонально)

    Intlayer використовує розширення модулів (module augmentation), щоб отримати переваги TypeScript і зміцнити вашу кодову базу.

    Переконайтеся, що ваша конфігурація TypeScript включає автоматично згенеровані типи:

    tsconfig.json
    Копіювати код

    Скопіюйте код у буфер обміну

    {  // ... ваші існуючі налаштування  include: [    // ... ваші існуючі включення    ".intlayer/**/*.ts", // Включити автоматично згенеровані типи  ],}

    Конфігурація Git

    Ми рекомендуємо ігнорувати файли, згенеровані Intlayer. Це дозволяє уникнути їх фіксації (commit) у вашому репозиторії Git.

    Для цього ви можете додати наступні інструкції до свого файлу .gitignore:

    .gitignore
    Копіювати код

    Скопіюйте код у буфер обміну

    # Ігнорувати файли, згенеровані Intlayer.intlayer

    Розширення VS Code

    Щоб покращити свій досвід розробки з Intlayer, ви можете встановити офіційне розширення Intlayer VS Code.

    Встановити з VS Code Marketplace

    Це розширення пропонує:

    • Автодоповнення для ключів перекладу.
    • Виявлення помилок у реальному часі для відсутніх перекладів.
    • Вбудований попередній перегляд (inline previews) перекладеного вмісту.
    • Швидкі дії для легкого створення та оновлення перекладів.

    Докладніше про те, як користуватися розширенням, див. у документації до розширення Intlayer VS Code.


    Подальші кроки

    Щоб піти далі, ви можете впровадити візуальний редактор або винести свій вміст за допомогою CMS.


    Посилання на документацію

    • Документація Intlayer
    • Документація Tanstack Start
    • Хук useIntlayer
    • Хук useLocale
    • Декларування вмісту
    • Конфігурація
    Tanstack Start
    Astro
    Alt+→

    На цій сторінці

      Обговорення анонімні та регулярно переглядаються для вирішення поширених проблем. Не соромтеся ділитися ідеями функцій, відгуками про документацію або будь-чим, що стосується Intlayer, ми використовуємо цю інформацію для формування нашої дорожньої карти та покращення продукту.

      npm install intlayer solid-intlayernpm install vite-intlayer --save-devnpx intlayer init
      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;
      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)$",      },    }),    solidPlugin({ ssr: true }),    intlayer(),  ],});
      import {  HeadContent,  Scripts,  createRootRouteWithContext,} 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";import { Route as LocaleRoute } from "./{-$locale}/route";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>  );};
      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,});
      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;
      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"]}    />  );};
      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;};
      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>  );}
      <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)}" />
      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;
      const RootComponent: ParentComponent = (props) => {  const params = LocaleRoute.useParams();  const locale = params()?.locale ?? defaultLocale;  return (    <html dir={getHTMLTextDir(locale)} lang={locale}>      {/* ... */}    </html>  );};
      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, intlayerProxy } from "vite-intlayer";export default defineConfig({  plugins: [    intlayerProxy(), // Проксі слід розміщувати перед сервером, якщо ви використовуєте Nitro    nitro(),    intlayer(),    tanstackStart({      router: {        routeFileIgnorePattern:          ".content.(ts|tsx|js|mjs|cjs|jsx|json|jsonc|json5)$",      },    }),    solid(),  ],});
      import { createFileRoute } from "@tanstack/solid-router";import { getIntlayer } from "intlayer";export const Route = createFileRoute("/{-$locale}/")({  component: RouteComponent,  head: ({ params }) => {    const { locale } = 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 },      ],    };  },});
      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),  });  // Отримати якийсь вміст за допомогою getIntlayer()  const content = getIntlayer("app", locale);  return { locale, content };});
      import { createFileRoute } from "@tanstack/solid-router";// Це створює спеціальний маршрут /[locale]/404// Він використовується і як прямий маршрут, і як компонент в інших файлахexport const Route = createFileRoute("/{-$locale}/404")({  component: NotFoundComponent,});// Експортується окремо, щоб його можна було повторно використовувати в notFoundComponent та catch-all маршрутахexport function NotFoundComponent() {  return (    <div>      <h1>404</h1>    </div>  );}
      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/неіснуюча-сторінка запускає це всередині макета /en  notFoundComponent: NotFoundComponent,});
      import { createFileRoute } from "@tanstack/solid-router";import { NotFoundComponent } from "./404";// Маршрут $ (splat/catch-all) збігається з будь-яким шляхом, що не збігається з іншими маршрутами// напр.: /en/якийсь/глибоко/вкладений/недійсний/шлях// Це гарантує, що ВСІ невідповідні шляхи всередині локалі показують сторінку 404// Без цього глибокі невідповідні шляхи могли б показувати порожню сторінку або помилкуexport const Route = createFileRoute("/{-$locale}/$")({  component: NotFoundComponent,});
      npx intlayer extract
      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)$",     },   }),   solidPlugin({ ssr: true }),   intlayer(),   intlayerCompiler(), ],});
      npm run build # Або rpm run dev
      {  // ... ваші існуючі налаштування  include: [    // ... ваші існуючі включення    ".intlayer/**/*.ts", // Включити автоматично згенеровані типи  ],}
      # Ігнорувати файли, згенеровані Intlayer.intlayer