Otrzymuj powiadomienia o nadchodzących wydaniach Intlayera
    Data utworzenia:2025-09-09Ostatnia aktualizacja:2025-09-09

    Przetłumacz swoją stronę Tanstack Start za pomocą Intlayer | Internacjonalizacja (i18n)

    Spis treści

    Ten przewodnik pokazuje, jak zintegrować Intlayer dla płynnej internacjonalizacji w projektach Tanstack Start z routingiem uwzględniającym lokalizację, wsparciem TypeScript oraz nowoczesnymi praktykami programistycznymi.

    Czym jest Intlayer?

    Intlayer to innowacyjna, open-source'owa biblioteka do internacjonalizacji (i18n), zaprojektowana, aby uprościć wsparcie wielojęzyczne w nowoczesnych aplikacjach webowych.

    Dzięki Intlayer możesz:

    • Łatwo zarządzać tłumaczeniami za pomocą deklaratywnych słowników na poziomie komponentów.
    • Dynamicznie lokalizować metadane, trasy i zawartość.
    • Zapewnić wsparcie TypeScript dzięki automatycznie generowanym typom, co poprawia autouzupełnianie i wykrywanie błędów.
    • Korzystaj z zaawansowanych funkcji, takich jak dynamiczne wykrywanie i przełączanie lokalizacji.
    • Włącz routing uwzględniający lokalizację za pomocą systemu routingu opartego na plikach Tanstack Start.

    Przewodnik krok po kroku, jak skonfigurować Intlayer w aplikacji Tanstack Start

    Zobacz Szablon aplikacji na GitHub.

    Krok 1: Utwórz projekt

    Rozpocznij od utworzenia nowego projektu TanStack Start, postępując zgodnie z przewodnikiem Start new project na stronie TanStack Start.

    Krok 2: Zainstaluj pakiety Intlayer

    Zainstaluj niezbędne pakiety, używając preferowanego menedżera pakietów:

    npm install intlayer react-intlayernpm install vite-intlayer --save-dev
    • intlayer

    • intlayer

      Podstawowy pakiet, który dostarcza narzędzia do internacjonalizacji dla zarządzania konfiguracją, tłumaczeń, deklaracji treści, transpilecji oraz poleceń CLI.

    • react-intlayer Pakiet integrujący Intlayer z aplikacją React. Zapewnia dostawców kontekstu oraz hooki do internacjonalizacji w React.

    • vite-intlayer Zawiera wtyczkę Vite do integracji Intlayer z bundlerem Vite, a także middleware do wykrywania preferowanego języka użytkownika, zarządzania ciasteczkami oraz obsługi przekierowań URL.

    Krok 3: Konfiguracja projektu

    Utwórz plik konfiguracyjny, aby skonfigurować języki swojej aplikacji:

    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;
    Za pomocą tego pliku konfiguracyjnego możesz ustawić lokalizowane adresy URL, przekierowania w middleware, nazwy ciasteczek, lokalizację i rozszerzenie deklaracji treści, wyłączyć logi Intlayer w konsoli i wiele więcej. Pełną listę dostępnych parametrów znajdziesz w dokumentacji konfiguracji.

    Krok 4: Integracja Intlayer w konfiguracji Vite

    Dodaj wtyczkę intlayer do swojej konfiguracji:

    vite.config.ts
    import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";import tsconfigPaths from "vite-tsconfig-paths";export default defineConfig({  plugins: [reactRouter(), tsconfigPaths(), intlayer()],});
    Wtyczka intlayer() dla Vite służy do integracji Intlayer z Vite. Zapewnia budowanie plików deklaracji treści oraz monitorowanie ich w trybie deweloperskim. Definiuje zmienne środowiskowe Intlayer w aplikacji Vite. Dodatkowo dostarcza aliasy optymalizujące wydajność.

    Krok 5: Utwórz komponenty layoutu

    Skonfiguruj swój główny layout oraz layouty specyficzne dla lokalizacji:

    Główny Layout

    src/routes/{-$locale}/route.tsx
    import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes";export const Route = createFileRoute("/{-$locale}")({  component: LayoutComponent,});function LayoutComponent() {  const { defaultLocale } = useLocale();  const { locale } = Route.useParams();  return (    <IntlayerProvider locale={defaultLocale}>      <Outlet />    </IntlayerProvider>  );}

    Krok 6: Zadeklaruj swoją treść

    Twórz i zarządzaj deklaracjami treści, aby przechowywać tłumaczenia:

    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: {      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",      }),    },    title: t({      en: "Welcome to Intlayer + TanStack Router",      es: "Bienvenido a Intlayer + TanStack Router",      fr: "Bienvenue à Intlayer + TanStack Router",    }),  },  key: "app",} satisfies Dictionary;export default appContent;
    Twoje deklaracje zawartości mogą być definiowane w dowolnym miejscu w Twojej aplikacji, pod warunkiem, że zostaną umieszczone w katalogu contentDir (domyślnie ./app). I będą miały rozszerzenie pliku deklaracji zawartości (domyślnie .content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}).
    Po więcej szczegółów odsyłamy do dokumentacji deklaracji zawartości.

    Krok 7: Tworzenie komponentów i hooków uwzględniających lokalizację

    Utwórz komponent LocalizedLink do nawigacji uwzględniającej lokalizację:

    src/components/localized-link.tsx
    import type { FC } from "react";import { Link, type LinkComponentProps } from "@tanstack/react-router";import { useLocale } from "react.intlayer";export const LOCALE_ROUTE = "{-$locale}" as const;// Główne narzędzieexport type RemoveLocaleParam<T> = T extends string  ? RemoveLocaleFromString<T>  : T;export type To = RemoveLocaleParam<LinkComponentProps["to"]>;type CollapseDoubleSlashes<S extends string> =  S extends `${infer H}//${infer T}` ? CollapseDoubleSlashes<`${H}/${T}`> : S;type LocalizedLinkProps = {  to?: To;} & Omit<LinkComponentProps, "to">;// Pomocnicze typytype RemoveAll<  S extends string,  Sub extends string,> = S extends `${infer H}${Sub}${infer T}` ? RemoveAll<`${H}${T}`, Sub> : S;type RemoveLocaleFromString<S extends string> = CollapseDoubleSlashes<  RemoveAll<S, typeof LOCALE_ROUTE>>;export const LocalizedLink: FC<LocalizedLinkProps> = (props) => {  const { locale } = useLocale();  const { localePrefix } = getPrefix(locale);  return (    <Link      {...props}      params={{        locale: localePrefix,        ...(typeof props?.params === "object" ? props?.params : {}),      }}      to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps["to"]}    />  );};

    Ten komponent ma dwa cele:

    • Usunięcie niepotrzebnego prefiksu {-$locale} z URL.
    • Wstrzyknięcie parametru locale do URL, aby zapewnić użytkownikowi bezpośrednie przekierowanie do zlokalizowanej ścieżki.

    Następnie możemy stworzyć hook useLocalizedNavigate do nawigacji programowej:

    src/hooks/useLocalizedNavigate.tsx
    import { useLocale } from "react.intlayer";import { useNavigate } from "@tanstack/react-router";import { LOCALE_ROUTE } from "@/components/localized-link";import type { FileRouteTypes } from "@/routeTree.gen";export const useLocalizedNavigate = () => {  const navigate = useNavigate();  const { locale } = useLocale();  type StripLocalePrefix<T extends string> = T extends    | `/${typeof LOCALE_ROUTE}`    | `/${typeof LOCALE_ROUTE}/`    ? "/"    : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}`      ? `/${Rest}`      : never;  type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>;  interface LocalizedNavigate {    (to: LocalizedTo): ReturnType<typeof navigate>;    (      opts: { to: LocalizedTo } & Record<string, unknown>    ): ReturnType<typeof navigate>;  }  const localizedNavigate: LocalizedNavigate = (args: any) => {    if (typeof args === "string") {      return navigate({ to: `/${LOCALE_ROUTE}${args}`, params: { locale } });    }    const { to, ...rest } = args;    const localedTo = `/${LOCALE_ROUTE}${to}` as any;    return navigate({ to: localedTo, params: { locale, ...rest } as any });  };  return localizedNavigate;};

    Krok 8: Wykorzystaj Intlayer na swoich stronach

    Uzyskaj dostęp do swoich słowników treści w całej aplikacji:

    Lokalizowana strona główna

    src/routes/{-$locale}/index.tsx
    import { createFileRoute } from "@tanstack/react-router";import { getIntlayer } from "intlayer";import { useIntlayer } from "react-intlayer";import LocaleSwitcher from "@/components/locale-switcher";import { LocalizedLink } from "@/components/localized-link";import { useLocalizedNavigate } from "@/hooks/useLocalizedNavigate";export const Route = createFileRoute("/{-$locale}/")({  component: RouteComponent,  head: ({ params }) => {    const { locale } = params;    const metaContent = getIntlayer("app", locale);    return {      meta: [        { title: metaContent.title },        { content: metaContent.meta.description, name: "description" },      ],    };  },});function RouteComponent() {  const content = useIntlayer("app");  const navigate = useLocalizedNavigate();  return (    <div>      <div>        {content.title}        <LocaleSwitcher />        <div>          <LocalizedLink to="/">{content.links.home}</LocalizedLink>          <LocalizedLink to="/about">{content.links.about}</LocalizedLink>        </div>        <div>          <button onClick={() => navigate({ to: "/" })}>            {content.links.home}          </button>          <button onClick={() => navigate({ to: "/about" })}>            {content.links.about}          </button>        </div>      </div>    </div>  );}
    Aby dowiedzieć się więcej o hooku useIntlayer, zapoznaj się z dokumentacją.

    Krok 9: Utwórz komponent przełącznika języka (Locale Switcher)

    Utwórz komponent, który pozwoli użytkownikom zmieniać języki:

    src/components/locale-switcher.tsx
    import type { FC } from "react";import { useLocation } from "@tanstack/react-router";import {  getHTMLTextDir,  getLocaleName,  getPathWithoutLocale,  getPrefix,} from "intlayer";import { setLocaleInStorage, useIntlayer, useLocale } from "react-intlayer";import { LocalizedLink, To } from "./localized-link";export const LocaleSwitcher: FC = () => {  const { localeSwitcherLabel } = useIntlayer("locale-switcher");  const { pathname } = useLocation();  const { availableLocales, locale } = useLocale();  const pathWithoutLocale = getPathWithoutLocale(pathname);  return (    <ol>      {availableLocales.map((localeEl) => (        <li key={localeEl}>          <LocalizedLink            aria-current={localeEl === locale ? "page" : undefined}            aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeEl)}`}            onClick={() => setLocaleInStorage(localeEl)}            params={{ locale: getPrefix(localeEl).localePrefix }}          >            <span>              {/* Lokalizacja - np. FR */}              {localeItem}            </span>            <span>              {/* Język w swojej własnej lokalizacji - np. Français */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* Język w bieżącej lokalizacji - np. Francés przy ustawionej lokalizacji Locales.SPANISH */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>              {/* Język po angielsku - np. French */}              {getLocaleName(localeItem, Locales.ENGLISH)}            </span>          </LocalizedLink>        </li>      ))}    </ol>  );};
    Aby dowiedzieć się więcej o hooku useLocale, zapoznaj się z dokumentacją.

    Krok 10: Dodaj zarządzanie atrybutami HTML (opcjonalnie)

    Utwórz hook do zarządzania atrybutami lang i dir w HTML:

    src/hooks/useI18nHTMLAttributes.tsx
    // src/hooks/useI18nHTMLAttributes.tsximport { getHTMLTextDir } from "intlayer";import { useEffect } from "react";import { useLocale } from "react-intlayer";export const useI18nHTMLAttributes = () => {  const { locale } = useLocale();  useEffect(() => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  }, [locale]);};

    Następnie użyj go w swoim komponencie root:

    src/routes/{-$locale}/index.tsx
    import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router";import { IntlayerProvider, useLocale } from "react-intlayer";import { useI18nHTMLAttributes } from "@/hooks/useI18nHTMLAttributes"; // importuj hookexport const Route = createFileRoute("/{-$locale}")({  component: LayoutComponent,});function LayoutComponent() {  useI18nHTMLAttributes(); // dodaj tę linię  const { defaultLocale } = useLocale();  const { locale } = Route.useParams();  return (    <IntlayerProvider locale={locale ?? defaultLocale}>      <Outlet />    </IntlayerProvider>  );}

    Krok 11: Dodaj middleware (opcjonalnie)

    Możesz również użyć intlayerProxy, aby dodać routing po stronie serwera do swojej aplikacji. Ten plugin automatycznie wykryje aktualny locale na podstawie URL i ustawi odpowiedni cookie locale. Jeśli nie zostanie określony żaden locale, plugin wybierze najbardziej odpowiedni locale na podstawie preferencji językowych przeglądarki użytkownika. Jeśli nie zostanie wykryty żaden locale, nastąpi przekierowanie do domyślnego locale.

    Uwaga: aby używać intlayerProxy w produkcji, musisz przenieść pakiet vite-intlayer z devDependencies do dependencies.
    vite.config.ts
    import { reactRouter } from "@react-router/dev/vite";import tailwindcss from "@tailwindcss/vite";import { defineConfig } from "vite";import { intlayer, intlayerProxy } from "vite-intlayer";import tsconfigPaths from "vite-tsconfig-paths";export default defineConfig({  plugins: [    tailwindcss(),    reactRouter(),    tsconfigPaths(),    intlayer(),    intlayerProxy(),  ],});

    Krok 12: Konfiguracja TypeScript (opcjonalnie)

    Intlayer używa rozszerzenia modułów (module augmentation), aby wykorzystać zalety TypeScript i wzmocnić Twoją bazę kodu.

    Upewnij się, że Twoja konfiguracja TypeScript zawiera automatycznie generowane typy:

    tsconfig.json
    {  // ... Twoje istniejące konfiguracje  include: [    // ... Twoje istniejące include    ".intlayer/**/*.ts", // Dołącz automatycznie generowane typy  ],}

    Konfiguracja Git

    Zaleca się ignorowanie plików generowanych przez Intlayer. Pozwala to uniknąć ich zatwierdzania do repozytorium Git.

    Aby to zrobić, możesz dodać następujące instrukcje do pliku .gitignore:

    .gitignore
    # Ignoruj pliki generowane przez Intlayer.intlayer

    Rozszerzenie VS Code

    Aby poprawić swoje doświadczenie deweloperskie z Intlayer, możesz zainstalować oficjalne rozszerzenie Intlayer dla VS Code.

    Zainstaluj z Marketplace VS Code

    To rozszerzenie oferuje:

    • Autouzupełnianie kluczy tłumaczeń.
    • Wykrywanie błędów w czasie rzeczywistym dla brakujących tłumaczeń.
    • Podgląd w linii przetłumaczonej zawartości.
    • Szybkie akcje umożliwiające łatwe tworzenie i aktualizowanie tłumaczeń.

    Aby uzyskać więcej informacji na temat korzystania z rozszerzenia, zapoznaj się z dokumentacją rozszerzenia Intlayer VS Code.


    Idź dalej

    Aby pójść dalej, możesz zaimplementować edytor wizualny lub wyodrębnić swoją zawartość, korzystając z CMS.


    Odnośniki do dokumentacji

    Ten kompleksowy przewodnik zawiera wszystko, co potrzebne do integracji Intlayer z Tanstack Start, aby uzyskać w pełni zinternacjonalizowaną aplikację z obsługą trasowania uwzględniającego lokalizację oraz wsparciem dla TypeScript.

    Otrzymuj powiadomienia o nadchodzących wydaniach Intlayera