Creation:2025-08-23Last update:2026-05-31

    Przetłumacz swoją stronę Create React App za pomocą Intlayer | Internacjonalizacja (i18n)

    ide.intlayer.org

    Zobacz Szablon aplikacji na GitHub.

    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:

    • Łatwe zarządzanie tłumaczeniami za pomocą deklaratywnych słowników na poziomie komponentów.
    • Dynamiczna lokalizacja metadanych, tras i treści.
    • Zapewnienie wsparcia dla TypeScript dzięki automatycznie generowanym typom, co poprawia autouzupełnianie i wykrywanie błędów.
    • Korzystanie z zaawansowanych funkcji, takich jak dynamiczne wykrywanie i zmiana lokalizacji.

    Przewodnik krok po kroku, jak skonfigurować Intlayer w aplikacji React

    1. Instalacja zależności

      Zainstaluj niezbędne pakiety za pomocą npm:

      bash
      npm install intlayer react-intlayer react-scripts-intlayernpx intlayer init
      • intlayer

        Główny pakiet, który dostarcza narzędzia do internacjonalizacji do 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.

      • react-scripts-intlayer

        Zawiera polecenia react-scripts-intlayer oraz wtyczki do integracji Intlayer z aplikacją opartą na Create React App. Te wtyczki bazują na craco i zawierają dodatkową konfigurację dla bundlera Webpack.

    2. Konfiguracja Twojego projektu

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

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [
            Locales.ENGLISH,
            Locales.FRENCH,
            Locales.SPANISH,
            // Twoje inne lokalizacje
          ],
          defaultLocale: Locales.ENGLISH,
        },
      };
      
      export default config;
      Za pomocą tego pliku konfiguracyjnego możesz ustawić lokalizowane adresy URL, przekierowania w middleware, nazwy ciasteczek, lokalizację i rozszerzenie deklaracji zawartości, wyłączyć logi Intlayer w konsoli i wiele więcej. Pełną listę dostępnych parametrów znajdziesz w dokumentacji konfiguracyjnej.
    3. Zintegruj Intlayer w swojej konfiguracji CRA

      Zmień swoje skrypty, aby używać react-intlayer

      package.json
        "scripts": {    "build": "react-scripts-intlayer build",    "start": "react-scripts-intlayer start",    "transpile": "intlayer build"  },
      Skrypty react-scripts-intlayer bazują na CRACO. Możesz również zaimplementować własną konfigurację opartą na wtyczce intlayer craco. Zobacz przykład tutaj.
    4. Zadeklaruj swoją zawartość

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

      src/app.content.tsx
      import { t, type Dictionary } from "intlayer";
      import React, { type ReactNode } from "react";
      
      const appContent = {
        key: "app",
        content: {
          getStarted: t<ReactNode>({
            en: (
              <>
                Edit <code>src/App.tsx</code> and save to reload
              </>
            ),
            fr: (
              <>
                Éditez <code>src/App.tsx</code> et enregistrez pour recharger
              </>
            ),
            es: (
              <>
                Edytuj <code>src/App.tsx</code> i zapisz, aby przeładować
              </>
            ),
          }),
          reactLink: {
            href: "https://reactjs.org",
            content: t({
              en: "Learn React",
              fr: "Apprendre React",
              es: "Aprender React",
            }),
          },
        },
      } 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 ./src). I będą miały rozszerzenie pliku deklaracji zawartości (domyślnie .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Aby uzyskać więcej szczegółów, zapoznaj się z dokumentacją deklaracji zawartości.
      Jeśli Twój plik zawartości zawiera kod TSX, powinieneś rozważyć import import React from "react"; w swoim pliku zawartości.
    5. Wykorzystaj Intlayer w swoim kodzie

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

      src/App.tsx
      import logo from "./logo.svg";
      import "./App.css";
      import type { FC } from "react";
      import { IntlayerProvider, useIntlayer } from "react-intlayer";
      
      const AppContent: FC = () => {
        const content = useIntlayer("app");
      
        return (
          <div className="App">
            <img src={logo} className="App-logo" alt="logo" />
      
            {content.getStarted}
            <a
              className="App-link"
              href={content.reactLink.href.value}
              target="_blank"
              rel="noopener noreferrer"
            >
              {content.reactLink.content}
            </a>
          </div>
        );
      };
      
      const App: FC = () => (
        <IntlayerProvider>
          <AppContent />
        </IntlayerProvider>
      );
      
      export default App;
      Uwaga: Jeśli chcesz użyć swojej zawartości w atrybucie typu string, takim jak alt, title, href, aria-label itp., musisz wywołać wartość funkcji, na przykład:
      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)}" />
      Aby dowiedzieć się więcej o hooku useIntlayer, zapoznaj się z dokumentacją.
    6. Zmień język swojej zawartości

      Opcjonalne

      Aby zmienić język swojej zawartości, możesz użyć funkcji setLocale dostarczonej przez hook useLocale. Funkcja ta pozwala ustawić lokalizację aplikacji i odpowiednio zaktualizować zawartość.

      src/components/LocaleSwitcher.tsx
      import { Locales } from "intlayer";
      import { useLocale } from "react-intlayer";
      
      const LocaleSwitcher = () => {
        const { setLocale } = useLocale();
      
        return (
          <button onClick={() => setLocale(Locales.English)}>
            Change Language to English
          </button>
        );
      };
      Aby dowiedzieć się więcej o hooku useLocale, zapoznaj się z dokumentacją.
    7. Dodaj lokalizowane routingi do swojej aplikacji

      Opcjonalne

      Celem tego kroku jest utworzenie unikalnych ścieżek dla każdego języka. Jest to przydatne dla SEO oraz przyjaznych dla SEO adresów URL. Przykład:

      plaintext
      - https://example.com/about- https://example.com/es/about- https://example.com/fr/about
      Domyślnie trasy nie mają prefiksu dla domyślnej lokalizacji. Jeśli chcesz dodać prefiks dla domyślnej lokalizacji, możesz ustawić opcję middleware.prefixDefault na true w swojej konfiguracji. Więcej informacji znajdziesz w dokumentacji konfiguracji.

      Aby dodać lokalizowane routingi do swojej aplikacji, możesz utworzyć komponent LocaleRouter, który opakuje trasy Twojej aplikacji i obsłuży routing oparty na lokalizacji. Oto przykład użycia React Router:

      src/components/LocaleRouter.tsx
      // Importowanie niezbędnych zależności i funkcji
      import { type Locales, configuration, getPathWithoutLocale } from "intlayer"; // Funkcje narzędziowe i typy z 'intlayer'
      // Funkcje narzędziowe i typy z 'intlayer'
      import type { FC, PropsWithChildren } from "react"; // Typy React dla komponentów funkcyjnych i propsów
      import { IntlayerProvider } from "react-intlayer"; // Provider dla kontekstu internacjonalizacji
      import {
        BrowserRouter,
        Routes,
        Route,
        Navigate,
        useLocation,
      } from "react-router-dom"; // Komponenty routera do zarządzania nawigacją
      
      // Destrukturyzacja konfiguracji z Intlayer
      const { internationalization, middleware } = configuration;
      const { locales, defaultLocale } = internationalization;
      
      /**
       * Komponent obsługujący lokalizację i opakowujący dzieci w odpowiedni kontekst lokalizacji.
       * Zarządza wykrywaniem i walidacją lokalizacji na podstawie URL.
       */
      const AppLocalized: FC<PropsWithChildren<{ locale: Locales }>> = ({
        children,
        locale,
      }) => {
        const { pathname, search } = useLocation(); // Pobierz aktualną ścieżkę URL
      
        // Określ bieżącą lokalizację, domyślnie używając domyślnej, jeśli nie jest podana
        const currentLocale = locale ?? defaultLocale;
      
        // Usuń prefiks lokalizacji ze ścieżki, aby utworzyć bazową ścieżkę
        const pathWithoutLocale = getPathWithoutLocale(
          pathname // Aktualna ścieżka URL
        );
      
        /**
         * Jeśli middleware.prefixDefault jest prawdziwe, domyślna lokalizacja powinna zawsze mieć prefiks.
         */
        if (middleware.prefixDefault) {
          // Waliduj lokalizację
          if (!locale || !locales.includes(locale)) {
            // Przekieruj do domyślnej lokalizacji z zaktualizowaną ścieżką
            return (
              <Navigate
                to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
                replace // Zamień bieżący wpis w historii na nowy
              />
            );
          }
      
          // Opakuj dzieci w IntlayerProvider i ustaw bieżącą lokalizację
          return (
            <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
          );
        } else {
          /**
           * Gdy middleware.prefixDefault jest false, domyślna lokalizacja nie jest poprzedzona prefiksem.
           * Upewnij się, że bieżąca lokalizacja jest prawidłowa i nie jest domyślną lokalizacją.
           */
          if (
            currentLocale.toString() !== defaultLocale.toString() &&
            !locales
              .filter(
                (locale) => locale.toString() !== defaultLocale.toString() // Wyklucz domyślną lokalizację
              )
              .includes(currentLocale) // Sprawdź, czy bieżąca lokalizacja znajduje się na liście ważnych lokalizacji
          ) {
            // Przekieruj do ścieżki bez prefiksu lokalizacji
            return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
          }
      
          // Opakuj dzieci w IntlayerProvider i ustaw bieżącą lokalizację
          return (
            <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
          );
        }
      };
      
      /**
       * Komponent routera, który ustawia trasy specyficzne dla lokalizacji.
       * Używa React Router do zarządzania nawigacją i renderowania zlokalizowanych komponentów.
       */
      export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
        <BrowserRouter>
          <Routes>
            {locales
              .filter(
                (locale) => middleware.prefixDefault || locale !== defaultLocale
              )
              .map((locale) => (
                <Route
                  // Wzorzec ścieżki do przechwycenia lokalizacji (np. /en/, /fr/) i dopasowania wszystkich kolejnych ścieżek
                  path={`/${locale}/*`}
                  key={locale}
                  element={<AppLocalized locale={locale}>{children}</AppLocalized>} // Opakowuje dzieci zarządzaniem lokalizacją
                />
              ))}
      
            {
              // Jeśli prefiksowanie domyślnej lokalizacji jest wyłączone, renderuj dzieci bezpośrednio na ścieżce głównej
              !middleware.prefixDefault && (
                <Route
                  path="*"
                  element={
                    <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
                  } // Opakowuje dzieci zarządzaniem lokalizacją
                />
              )
            }
          </Routes>
        </BrowserRouter>
      );

      Następnie możesz użyć komponentu LocaleRouter w swojej aplikacji:

      src/App.tsx
      import { LocaleRouter } from "./components/LocaleRouter";
      import type { FC } from "react";
      
      // ... Twój komponent AppContent
      
      const App: FC = () => (
        <LocaleRouter>
          <AppContent />
        </LocaleRouter>
      );
    8. Zmiana URL po zmianie lokalizacji

      Opcjonalne

      Aby zmienić URL podczas zmiany lokalizacji, możesz użyć właściwości onLocaleChange dostarczonej przez hook useLocale. Równolegle możesz użyć hooków useLocation i useNavigate z react-router-dom, aby zaktualizować ścieżkę URL.

      src/components/LocaleSwitcher.tsx
      import { useLocation, useNavigate } from "react-router-dom";
      import {
        Locales,
        getHTMLTextDir,
        getLocaleName,
        getLocalizedUrl,
      } from "intlayer";
      import { useLocale } from "react-intlayer";
      import { type FC } from "react";
      
      const LocaleSwitcher: FC = () => {
        const { pathname, search } = useLocation(); // Pobierz aktualną ścieżkę URL. Przykład: /fr/about?foo=bar
        const navigate = useNavigate();
      
        const { locale, availableLocales, setLocale } = useLocale({
          onLocaleChange: (locale) => {
            // Konstrukcja URL z zaktualizowaną lokalizacją
            // Przykład: /es/about?foo=bar
            const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
      
            // Aktualizacja ścieżki URL
            navigate(pathWithLocale);
          },
        });
      
        return (
          <div>
            <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
            <div id="localePopover" popover="auto">
              {availableLocales.map((localeItem) => (
                <a
                  href={getLocalizedUrl(location.pathname, localeItem)}
                  hrefLang={localeItem}
                  aria-current={locale === localeItem ? "page" : undefined}
                  onClick={(e) => {
                    e.preventDefault();
                    setLocale(localeItem);
                  }}
                  key={localeItem}
                >
                  <span>
                    {/* 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>
                </a>
              ))}
            </div>
          </div>
        );
      };

      Odwołania do dokumentacji:

    9. Zmiana atrybutów języka i kierunku w tagu HTML

      Opcjonalne

      Gdy Twoja aplikacja obsługuje wiele języków, kluczowe jest, aby zaktualizować atrybuty lang i dir w tagu <html>, tak aby odpowiadały bieżącej lokalizacji. Zapewnia to:

      • Dostępność: Czytniki ekranu i technologie wspomagające polegają na poprawnym atrybucie lang, aby prawidłowo wymawiać i interpretować zawartość.
      • Renderowanie tekstu: Atrybut dir (kierunek) zapewnia, że tekst jest wyświetlany w odpowiedniej kolejności (np. od lewej do prawej dla języka angielskiego, od prawej do lewej dla arabskiego lub hebrajskiego), co jest kluczowe dla czytelności.
      • SEO: Wyszukiwarki używają atrybutu lang, aby określić język strony, co pomaga w dostarczaniu odpowiednio zlokalizowanych treści w wynikach wyszukiwania.

      Poprzez dynamiczną aktualizację tych atrybutów przy zmianie lokalizacji, zapewniasz spójne i dostępne doświadczenie dla użytkowników we wszystkich obsługiwanych językach.

      Implementacja hooka

      Utwórz niestandardowy hook do zarządzania atrybutami HTML. Hook nasłuchuje zmian lokalizacji i odpowiednio aktualizuje atrybuty:

      src/hooks/useI18nHTMLAttributes.tsx
      import { useEffect } from "react";
      import { useLocale } from "react-intlayer";
      import { getHTMLTextDir } from "intlayer";
      
      /**
       * Aktualizuje atrybuty `lang` i `dir` elementu HTML <html> na podstawie bieżącej lokalizacji.
       * - `lang`: Informuje przeglądarki i wyszukiwarki o języku strony.
       * - `dir`: Zapewnia poprawny kierunek czytania (np. 'ltr' dla angielskiego, 'rtl' dla arabskiego).
       *
       * Ta dynamiczna aktualizacja jest niezbędna dla prawidłowego renderowania tekstu, dostępności i SEO.
       */
      export const useI18nHTMLAttributes = () => {
        const { locale } = useLocale();
      
        useEffect(() => {
          // Aktualizuje atrybut języka na bieżącą lokalizację.
          document.documentElement.lang = locale;
      
          // Ustawia kierunek tekstu na podstawie bieżącej lokalizacji.
          document.documentElement.dir = getHTMLTextDir(locale);
        }, [locale]);
      };

      Użycie Hooka w Twojej Aplikacji

      Zintegruj hook w swoim głównym komponencie, aby atrybuty HTML były aktualizowane za każdym razem, gdy zmienia się locale:

      src/App.tsx
      import type { FC } from "react";
      import { IntlayerProvider, useIntlayer } from "react-intlayer";
      import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
      import "./App.css";
      
      const AppContent: FC = () => {
        // Zastosuj hook do aktualizacji atrybutów lang i dir tagu <html> na podstawie lokalizacji.
        useI18nHTMLAttributes();
      
        // ... Reszta twojego komponentu
      };
      
      const App: FC = () => (
        <IntlayerProvider>
          <AppContent />
        </IntlayerProvider>
      );
      
      export default App;

      Wprowadzając te zmiany, Twoja aplikacja:

      • Zapewni, że atrybut language (lang) poprawnie odzwierciedla bieżącą lokalizację, co jest ważne dla SEO i zachowania przeglądarki.
      • Dostosuje kierunek tekstu (dir) zgodnie z lokalizacją, poprawiając czytelność i użyteczność dla języków o różnych kierunkach czytania.
      • Zapewni bardziej dostępne doświadczenie, ponieważ technologie wspomagające polegają na tych atrybutach, aby działać optymalnie.

    Konfiguracja TypeScript

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

    Autouzupełnianie

    Błąd tłumaczenia

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

    tsconfig.json
    {  // ... Twoje istniejące konfiguracje TypeScript  "include": [    // ... Twoje istniejące konfiguracje TypeScript    ".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 VS Code Marketplace

    To rozszerzenie oferuje:

    • Autouzupełnianie kluczy tłumaczeń.
    • Wykrywanie błędów w czasie rzeczywistym dla brakujących tłumaczeń.
    • Podglądy 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 dla VS Code.

    Idź dalej

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