Skip to content

Latest commit

 

History

History
634 lines (464 loc) · 27.9 KB

File metadata and controls

634 lines (464 loc) · 27.9 KB
createdAt 2024-03-07
updatedAt 2026-05-31
title Astro + React i18n - Повний посібник з перекладу вашого застосунку
description Більше ніякого i18next. Посібник 2026 зі створення багатомовного (i18n) застосунку Astro + React. Перекладайте за допомогою ШІ-агентів та оптимізуйте розмір бандлу, SEO та продуктивність.
keywords
інтернаціоналізація
документація
Intlayer
Astro
React
i18n
JavaScript
slugs
doc
environment
astro
react
applicationTemplate https://github.com/aymericzip/intlayer-astro-template
applicationShowcase https://intlayer-astro-template.vercel.app
history
version date changes
8.9.0
2026-05-04
Оновлення використання API useIntlayer у Solid для прямого доступу до властивостей
version date changes
7.5.9
2025-12-30
Додано команду init
version date changes
6.2.0
2025-10-03
Оновлення інтеграції Astro, конфігурації та використання

Перекладіть свій сайт Astro + React за допомогою Intlayer | Інтернаціоналізація (i18n)

<iframe src="https://ide.intlayer.org/aymericzip/intlayer-astro-template?file=intlayer.config.ts" className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full" title="Demo CodeSandbox - Як інтернаціоналізувати ваш додаток за допомогою Intlayer" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" loading="lazy" /> <iframe src="https://intlayer-astro-template.vercel.app" className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full" title="Демо - intlayer-astro-template" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" loading="lazy" />

Зміст

Чому варто обрати Intlayer, а не альтернативи?

Порівняно з основними рішеннями, такими як astro-i18n або i18next, Intlayer — це рішення, яке має такі інтегровані оптимізації, як:

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

Замість того, щоб завантажувати великі файли JSON на свої сторінки, завантажуйте лише необхідний вміст. Intlayer допомагає зменшити розмір бандлу і сторінок до 50%.

Організація вмісту за окремими областями (scoping) полегшує технічне обслуговування великомасштабних програм. Ви можете скопіювати або видалити окрему папку функцій без розумового навантаження перегляду всієї кодової бази вмісту. Крім того, Intlayer повністю типізований (fully typed), щоб забезпечити точність вашого вмісту.

Спільне розміщення вмісту зменшує контекст, необхідний для великих мовних моделей (LLM). Intlayer також постачається з набором інструментів, наприклад CLI для перевірки відсутніх перекладів,LSP, MCP і навички агента, щоб зробити роботу розробника (DX) ще зручнішою для агентів ШІ.

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

Підключення великих файлів JSON до компонентів може призвести до проблем з продуктивністю та реакцією. Intlayer оптимізує завантаження вмісту під час збірки (build time).

Більше ніж просто рішення i18n, Intlayer пропонує власний візуальний редактор і повний CMS, щоб допомогти вам керувати своїм багатомовним вмістом у реальному часі, спрощуючи співпрацю з перекладачами, копірайтерами та іншими членами команди. Контент можна зберігати локально та/або віддалено.


Покрокова інструкція з налаштування Intlayer в Astro + React

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

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

npm install intlayer astro-intlayer react react-dom react-intlayer @astrojs/react

npx intlayer init
pnpm add intlayer astro-intlayer react react-dom react-intlayer @astrojs/react

pnpm intlayer init
yarn add intlayer astro-intlayer react react-dom react-intlayer @astrojs/react

yarn intlayer init
bun add intlayer astro-intlayer react react-dom react-intlayer @astrojs/react

bun x intlayer init
  • intlayer Основний пакет, що надає інструменти i18n для керування конфігурацією, перекладами, декларацією вмісту, транспіляцією та командами CLI.

  • astro-intlayer Плагін інтеграції Astro для зв'язку Intlayer з бандлером Vite; він також включає middleware для визначення бажаної мови користувача, керування cookie та обробки перенаправлень URL.

  • react, react-dom Основні пакети React, що використовуються для рендерингу компонентів React у браузері.

  • react-intlayer Пакет для інтеграції Intlayer у додатки React. Він надає IntlayerProvider, а також хуки useIntlayer та useLocale для інтернаціоналізації в React.

  • @astrojs/react Офіційна інтеграція Astro, яка дозволяє використовувати React component islands.

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

import { Locales, type IntlayerConfig } from "intlayer";

const config: IntlayerConfig = {
  internationalization: {
    locales: [
      Locales.ENGLISH,
      Locales.FRENCH,
      Locales.SPANISH,
      Locales.UKRAINIAN,
      // Ваші інші локалі
    ],
    defaultLocale: Locales.ENGLISH,
  },
};

export default config;

Через цей конфігураційний файл ви можете налаштувати локалізовані URL-адреси, перенаправлення middleware, імена cookie, розташування та розширення декларацій вмісту, вимкнути логи Intlayer у консолі та багато іншого. Повний список доступних параметрів дивіться в документації з конфігурації.

Додайте плагін intlayer до вашої конфігурації Astro та інтеграцію React.

// @ts-check

import { intlayer } from "astro-intlayer";
import react from "@astrojs/react";
import { defineConfig } from "astro/config";

// https://astro.build/config
export default defineConfig({
  integrations: [intlayer(), react()],
});

Плагін інтеграції intlayer() використовується для інтеграції Intlayer з Astro. Він забезпевує генерацію файлів декларації вмісту та стежить за ними в режимі розробки. Він визначає змінні середовища Intlayer всередині додатка Astro та надає аліаси для оптимізації продуктивності.

Інтеграція react() дозволяє використовувати React component islands за допомогою client:only="react".

Створюйте та керуйте своїми деклараціями вмісту для зберігання перекладів:

import { t, type Dictionary } from "intlayer";
import type { ReactNode } from "react";

const appContent = {
  key: "app",
  content: {
    title: t({
      en: "Hello World",
      fr: "Bonjour le monde",
      es: "Hola mundo",
      uk: "Привіт Світе",
    }),
  },
} satisfies Dictionary;

export default appContent;

Декларації вмісту можна визначати в будь-якому місці вашого додатка, за умови, що вони включені в contentDir (за замовчуванням ./src) і відповідають розширенню файлів декларації вмісту (за замовчуванням .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).

Для отримання додаткової інформації дивіться документацію з декларації вмісту.

Ви можете використовувати словники безпосередньо у ваших .astro файлах, використовуючи основні допоміжні функції, експортовані з intlayer. Вам також слід додати метадані SEO (такі як hreflang та канонічні посилання) на кожній сторінці та додати React island для інтерактивного вмісту на стороні клієнта.

---
import {
  getIntlayer,
  getLocaleFromPath,
  getLocalizedUrl,
  getHTMLTextDir,
  getPrefix,
  localeMap,
  defaultLocale,
  type LocalesValues,
} from "intlayer";
import { ReactIsland } from "../../components/react/ReactIsland";

export const getStaticPaths = () => {
  return localeMap(({ locale }) => ({
    params: { locale: getPrefix(locale).localePrefix },
  }));
};

const locale = getLocaleFromPath(Astro.url.pathname) as LocalesValues;
const { title } = getIntlayer("app", locale);
---

<!doctype html>
<html lang={locale} dir={getHTMLTextDir(locale)}>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <title>{title}</title>

    <!-- Канонічне посилання: Повідомляє пошуковим системам основну версію цієї сторінки -->
    <link
      rel="canonical"
      href={new URL(getLocalizedUrl(Astro.url.pathname, locale), Astro.site)}
    />

    <!-- Hreflang: Повідомляє Google про всі локалізовані версії -->
    {
      localeMap(({ locale: mapLocale }) => (
        <link
          rel="alternate"
          hreflang={mapLocale}
          href={new URL(
            getLocalizedUrl(Astro.url.pathname, mapLocale),
            Astro.site
          )}
        />
      ))
    }

    <!-- x-default: Резервний варіант, коли мова не відповідає мові користувача -->
    <link
      rel="alternate"
      hreflang="x-default"
      href={new URL(
        getLocalizedUrl(Astro.url.pathname, defaultLocale),
        Astro.site
      )}
    />
  </head>
  <body>
    <!-- React island рендерить увесь інтерактивний вміст, включаючи перемикач мов -->
    <ReactIsland locale={locale} client:only="react" />
  </body>
</html>

Якщо ви хочете використовувати свій контент в атрибуті рядка, такому як alt, title, href, aria-label тощо, ви можете використовувати значення функції, наприклад:

<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)}" />

Примітка щодо налаштування маршрутизації: Структура каталогів, яку ви використовуєте, залежить від параметра middleware.routing у intlayer.config.ts:

  • prefix-no-default (за замовчуванням): Зберігає мову за замовчуванням у корені (без префікса) та додає префікси до інших. Використовуйте [...locale], щоб охопити всі випадки.
  • prefix-all: Усі URL-адреси отримують префікс мови. Ви можете використовувати стандартний [locale], якщо вам не потрібно окремо обробляти корінь.
  • search-param або no-prefix: Каталоги мов не потрібні. Мова керується за допомогою параметрів запиту або cookie.

Створіть компонент island, який обгортає ваш додаток React і приймає мову, визначену сервером:

/** @jsxImportSource react */
import { IntlayerProvider, useIntlayer } from "react-intlayer";
import { type LocalesValues } from "intlayer";
import { LocaleSwitcher } from "./LocaleSwitcher";

function App() {
  const { title } = useIntlayer("app");

  return (
    <div>
      <h1>{title}</h1>
      <LocaleSwitcher />
    </div>
  );
}

export function ReactIsland({ locale }: { locale: LocalesValues }) {
  return (
    <IntlayerProvider locale={locale}>
      <App />
    </IntlayerProvider>
  );
}

Проп locale передається зі сторінки Astro (визначення на стороні сервера) до IntlayerProvider, що слугує початковою мовою для всіх хуків React всередині дерева.

Створіть компонент React LocaleSwitcher, який зчитує доступні мови та переходить за локалізованою URL-адресою, коли користувач обирає нову мову:

/** @jsxImportSource react */
import { useLocale } from "react-intlayer";
import { getLocalizedUrl, getLocaleName, type LocalesValues } from "intlayer";

export function LocaleSwitcher() {
  const { locale, availableLocales, setLocale } = useLocale({
    onLocaleChange: (newLocale: LocalesValues) => {
      // Перейти за локалізованою URL-адресою при зміні мови
      window.location.href = getLocalizedUrl(
        window.location.pathname,
        newLocale
      );
    },
  });

  return (
    <div className="locale-switcher">
      <span className="switcher-label">Змінити мову:</span>
      <div className="locale-buttons">
        {availableLocales.map((localeItem) => (
          <button
            key={localeItem}
            onClick={() => setLocale(localeItem)}
            className={`locale-btn ${localeItem === locale ? "active" : ""}`}
            disabled={localeItem === locale}
          >
            <span className="ls-own-name">{getLocaleName(localeItem)}</span>
            <span className="ls-current-name">
              {getLocaleName(localeItem, locale)}
            </span>
            <span class="ls-code">{localeItem.toUpperCase()}</span>
          </button>
        ))}
      </div>
    </div>
  );
}

Примітка щодо стійкості: Використання onLocaleChange для перенаправлення через window.location.href гарантує відвідування нової URL-адреси з мовним префіксом. Це дозволяє middleware Intlayer встановити cookie мови та запам'ятати вибір користувача для майбутніх візитів.

LocaleSwitcher повинен рендеритися всередині IntlayerProvider - використовуйте його у вашому компоненті island (як показано на кроці 6).

Intlayer пропонує інструменти для динамічного створення локалізованої карти сайту та файлу robots.txt.

Sitemap

Intlayer comes with a built-in sitemap generator to help you create a sitemap for your application easily. It handles localized routes and adds the necessary metadata for search engines.

The Intlayer generated sitemap supports the xhtml:link namespace (Hreflang XML Extensions). Unlike the default sitemap generators that only list raw URLs, Intlayer automatically creates the required bidirectional links between all language versions of a page (e.g., /about, /about?lang=fr, and /about?lang=es). This ensures search engines correctly index and serve the right language version to the right audience.

Створіть src/pages/sitemap.xml.ts для генерації карти сайту, що охоплює всі ваші локалізовані маршрути.

import type { APIRoute } from "astro";
import { generateSitemap, type SitemapUrlEntry } from "intlayer";

const pathList: SitemapUrlEntry[] = [
  { path: "/", changefreq: "daily", priority: 1.0 },
  { path: "/about", changefreq: "monthly", priority: 0.7 },
];

const SITE_URL = import.meta.env.SITE ?? "http://localhost:4321";

export const GET: APIRoute = async ({ site }) => {
  const xmlOutput = generateSitemap(pathList, { siteUrl: SITE_URL });

  return new Response(xmlOutput, {
    headers: { "Content-Type": "application/xml" },
  });
};

Robots.txt

Створіть src/pages/robots.txt.ts для керування скануванням пошуковими системами.

import type { APIRoute } from "astro";
import { getMultilingualUrls } from "intlayer";

const getAllMultilingualUrls = (urls: string[]) =>
  urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);

const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);

export const GET: APIRoute = ({ site }) => {
  const robotsTxt = [
    "User-agent: *",
    "Allow: /",
    ...disallowedPaths.map((path) => `Disallow: ${path}`),
    "",
    `Sitemap: ${new URL("/sitemap.xml", site).href}`,
  ].join("\n");

  return new Response(robotsTxt, {
    headers: { "Content-Type": "text/plain" },
  });
};

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

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

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

import { type IntlayerConfig } from "intlayer";

const config: IntlayerConfig = {
  // ... Інша частина вашої конфігурації
  compiler: {
    /**
     * Вказує, чи повинен бути включений компілятор.
     */
    enabled: true,

    /**
     * Визначає шлях до вихідних файлів
     */
    output: ({ fileName, extension }) => `./${fileName}${extension}`,

    /**
     * Вказує, чи повинні компоненти зберігатися після перетворення. Таким чином, компілятор можна запустити лише один раз для перетворення програми, а потім видалити.
     */
    saveComponents: false,

    /**
     * Префікс ключа словника
     */
    dictionaryKeyPrefix: "",
  },
};

export default config;

Запустіть екстрактор для перетворення компонентів і витягування вмісту

npx intlayer extract
pnpm intlayer extract
yarn intlayer extract
bun x intlayer extract

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

import { defineConfig } from "vite";
import { intlayer, intlayerCompiler } from "vite-intlayer";

export default defineConfig({
  plugins: [
    intlayer(),
    intlayerCompiler(), // Додає плагін компілятора
  ],
});
npm run build # Або npm run dev
pnpm run build # Or pnpm run dev
yarn build # Or yarn dev
bun run build # Or bun run dev

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

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

Autocompletion

Translation Error

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

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

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

Ми рекомендуємо ігнорувати файли, згенеровані Intlayer. Це запобігає їх потраплянню до вашого Git-репозиторію.

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

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

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

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

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

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

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

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


Поглиблюйте свої знання

Якщо ви хочете дізнатися більше, ви також можете впровадити Візуальний редактор або використовувати CMS, щоб винести ваш вміст назовні.