Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту
Історія версій
- "Початкова версія"v9.5.1026.09.2026
Вміст цієї сторінки перекладено за допомогою штучного інтелекту.
Переглянути останню версію оригінального вмісту англійськоюЯкщо у вас є ідея щодо покращення цієї документації, будь ласка, долучіться, надіславши pull request на GitHub.
Посилання на документацію на GitHubСкопіювати документацію у форматі Markdown в буфер обміну
Як інтернаціоналізувати ваш застосунок TanStack Start за допомогою use-intl у 2026 році
Зміст
Що таке use-intl?
use-intl - це незалежне від фреймворків ядро next-intl. Воно надає ті самі API useTranslations, useFormatter та IntlProvider, підтримку ICU MessageFormat і надійну інтеграцію з TypeScript без будь-якої залежності від Next.js. Це робить його одним із найпопулярніших варіантів для перекладу застосунків TanStack Start, і саме цю бібліотеку найчастіше радять ШІ-асистенти для цього стека.
TanStack Start не містить вбудованого шару i18n. Маршрутизація, визначення локалі, метадані SEO та генерація карти сайту (sitemap) залишаються за вами. Цей посібник охоплює все від початку до кінця:
- Маршрутизація з урахуванням локалі за допомогою необов'язкового сегмента
{-$locale}(/about,/fr/about). - Завантаження повідомлень для окремих маршрутів, завдяки чому сторінка завантажує лише потрібні простори імен і локаль, яку рендерить.
- Серверний рендеринг та гідратація без розбіжностей у тексті.
- Повне багатомовне SEO: перекладені
<title>та description, канонічна URL-адреса, альтернативиhreflangзx-default, локалі Open Graph, JSON-LD, sitemap з альтернативамиxhtml:link,robots.txtта пререндеринг кожної локалі.
Шукаєте інший стек? Перегляньте посібник з TanStack Start + Paraglide, посібник з TanStack Start + Lingui або посібник з TanStack Start + Intlayer.
Використовуєте Next.js? Перегляньте посібник з next-intl.
Що показує бенчмарк про use-intl на TanStack Start
Бенчмарк i18n запускає один і той самий застосунок TanStack Start на 10 сторінок і 10 локалей з кожною основною бібліотекою та вимірює, що насправді завантажує браузер.
Динамічне завантаження JSON
Ледаче завантаження перекладів під час виконання
Обмежений JSON (простори імен)
Простори імен перекладу для кожної сторінки
Бенчмарк продуктивності I18n
Що це за метрика?
Загальний стиснений у gzip розмір пакета бібліотеки інтернаціоналізації. Він включає лише провайдер та логіку отримання контенту після tree-shaking та мініфікації.
Чому це важливо?
Менший розмір бібліотеки зменшує початкове завантаження JavaScript, що призводить до швидшого завантаження та виконання на клієнті.
Перегляд як
Ключові показники для use-intl@4.14.2, виміряні 2026-09-26 (gzip):
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Конфігурація | Розмір бібліотеки | JS на сторінку | Витік іншої локалі | Витік іншої сторінки |
|---|---|---|---|---|
| Без i18n (базовий застосунок) | - | 111.0 KB | 0% | 0% |
use-intl (налаштування з цього посібника) | 75.9 KB | 128.7 KB | 0% | 0% |
@intlayer/use-intl (сумісність) | 6.7 KB | 129.4 KB | 0% | 0% |
react-intlayer (нативний Intlayer) | 4.5 KB | 126.8 KB | 0% | 0% |
Головні висновки:
- Розділяйте повідомлення за сторінками та завантажуйте їх для кожної локалі окремо. Це усуває обидва витоки, і саме це реалізовано в кроках нижче.
- Сам runtime залишається важким (~76 KB gzip), оскільки парсер ICU передається клієнту. Адаптер сумісності
@intlayer/use-intl(крок 17) зберігає абсолютно той самий API з розміром runtime близько ~7 KB.
Перегляньте повні дані: Звіт бенчмарку TanStack Start та репозиторій бенчмарку.
Порівняння функціональності на TanStack Start
Як use-intl виглядає на фоні інших популярних бібліотек для TanStack Start:
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Функція | react-intlayer (Intlayer) | use-intl | Paraglide JS | Lingui |
|---|---|---|---|---|
| Переклади поруч із компонентами | ✅ Спільне розташування (co-located) | ❌ Централізований JSON | ❌ Один файл JSON на локаль | ⚠️ Вихідний текст у компонентах |
| Інтеграція з TypeScript | ✅ Автоматично згенеровані типи | ✅ Через AppConfig | ✅ Типізовані функції повідомлень | ⚠️ Тільки макроси |
| Виявлення відсутніх перекладів | ✅ Помилки типів і попередження збірки | ⚠️ Фолбек під час виконання | ⚠️ Фолбек на базову локаль | ⚠️ Фолбек на вихідний текст |
| Розширений вміст (JSX, Markdown) | ✅ Пряма підтримка | ⚠️ Теги через t.rich | ⚠️ Рядки | ✅ JSX всередині <Trans> |
| Локалізована маршрутизація | ✅ Вбудовано | ❌ Вручну {-$locale} | ✅ urlPatterns + перезапис роутера | ❌ Вручну {-$locale} |
| Перемикання локалі без перезавантаження | ✅ Так | ✅ Так | ❌ Повне перезавантаження сторінки | ✅ Так |
| Плюралізація | ✅ На основі перелічення | ✅ ICU | ✅ Варіанти | ✅ ICU |
| ICU MessageFormat | ✅ Через format: "icu" | ✅ Нативно | ⚠️ Через плагін inlang | ✅ Нативно |
| Формати вмісту | ✅ .ts, .json, .md, .yaml... | ⚠️ .json | ⚠️ inlang JSON | ✅ PO, JSON, CSV |
| ШІ-переклад | ✅ Власний провайдер і ключ | ❌ Ні | ❌ Ні | ❌ Ні |
| Візуальний редактор / CMS | ✅ Локальний редактор + опціональна CMS | ❌ Зовнішні платформи | ⚠️ Застосунки екосистеми inlang | ❌ Зовнішні платформи |
| SEO-помічники (hreflang, sitemap) | ✅ Вбудовано | ❌ Вручну | ⚠️ Локалізовані URL, решта вручну | ❌ Вручну |
| Розмір під час виконання (gzip, бенчмарк) | 4.5 KB | 75.9 KB | 1.8 KB | 56.7 KB |
| Витік, найкраще налаштування (локаль / сторінка) | 0% / 0% | 0% / 0% | 49.7% / 0% | 8.6% / 0% |
| Відсутні переклади в CI | ✅ npx intlayer test | ⚠️ Не вбудовано | ⚠️ Не вбудовано | ✅ lingui compile --strict |
Показники розміру runtime та витоків взяті з бенчмарку TanStack Start. Витік вимірювався для найкращої конфігурації кожної бібліотеки.
Інші посібники з TanStack Start: Lingui, Paraglide JS та Intlayer.
Практики, яких варто дотримуватися
- Встановлюйте
langтаdirна тегу<html>для доступності, скринрідерів та пошукових систем. - Зберігайте одну URL-адресу на кожну локаль. Використовуйте префікс локалі (
/fr/about), а не лише перемикання через cookie, щоб кожна перекладена сторінка була доступна для сканування та поширення. - Розділяйте повідомлення за просторами імен (
common,home,about) та завантажуйте їх за маршрутами. - Завантажуйте лише активну локаль. Ніколи не імпортуйте файли всіх локалей у модуль, який надсилається клієнту.
- Зафіксуйте часовий пояс в
IntlProvider. Інакше дати форматуватимуться в часовому поясі сервера під час SSR і в часовому поясі відвідувача під час гідратації, що спричиняє розбіжності (hydration mismatches). - Перекладайте метадані та вказуйте
canonical,hreflangіx-defaultна кожній сторінці. - Генеруйте багатомовний sitemap та robots.txt, а також виконуйте пререндеринг кожної локалі.
- Використовуйте справжні посилання для перемикача мов, а не
<select>, щоб пошукові роботи могли виявити кожну мовну версію. - Типізуйте повідомлення, щоб відсутній ключ призводив до помилки під час компіляції.
Перегляньте наш посібник з інтернаціоналізації та SEO та посібник з hreflang.
Покроковий посібник з налаштування use-intl у застосунку TanStack Start
Ось структура проєкту, яку ми створимо:
Скопіюйте код у буфер обміну
Встановіть залежності
Почніть із проєкту TanStack Start, а потім додайте
use-intl:bashКопіювати кодСкопіюйте код у буфер обміну
- use-intl: надає
IntlProvider,useTranslations,useFormatterтаcreateTranslator(можна використовувати поза React, наприклад уhead()).
- use-intl: надає
Централізуйте конфігурацію локалей
Створіть єдине джерело правди для ваших локалей та допоміжних функцій URL. Усі інші файли (маршрути, SEO, sitemap, пререндеринг) імпортують дані звідси, тому додавання нової локалі виконується в один рядок.
Локаль за замовчуванням залишається без префікса (
/about), а інші локалі мають префікс (/fr/about). Це стратегія "за потребою" (as-needed): одна URL-адреса на сторінку для кожної локалі та короткі адреси для вашої основної аудиторії.src/i18n/config.tsКопіювати кодСкопіюйте код у буфер обміну
Створіть файли перекладів
Організуйте повідомлення за локалями та за просторами імен.
commonмістить те, що потрібно кожній сторінці (навігація, футер), а кожна окрема сторінка отримує власний файл, включно з метаданими.use-intl використовує ICU MessageFormat, тому множина, перемикачі (selects) та форматовані аргументи знаходяться безпосередньо в самому повідомленні.
messages/en/common.jsonКопіювати кодСкопіюйте код у буфер обміну
messages/en/about.jsonКопіювати кодСкопіюйте код у буфер обміну
messages/fr/common.jsonКопіювати кодСкопіюйте код у буфер обміну
messages/fr/about.jsonКопіювати кодСкопіюйте код у буфер обміну
Створіть
home.jsonтаким самим чином, з об'єктомmetadataта вмістом сторінки.Завантажуйте повідомлення за просторами імен та локалями
Цей завантажувач є найважливішим файлом для продуктивності.
import.meta.globвказує Vite генерувати один чанк на кожен JSON-файл. Маршрут, який запитує["about"]французькою мовою, завантажуєmessages/fr/about.jsonі нічого зайвого - саме так бенчмарк досягає 0% витоку локалей та 0% витоку сторінок.src/i18n/messages.tsКопіювати кодСкопіюйте код у буфер обміну
Типізуйте ваші повідомлення
Розширення модулів (module augmentation) забезпечує автодоповнення для
useTranslations("about")таt("counter.label"), а також помилку компіляції за наявності друкарських помилок або видалених ключів.src/i18n/use-intl.d.tsКопіювати кодСкопіюйте код у буфер обміну
Переконайтеся, що опція
resolveJsonModuleувімкнена у вашомуtsconfig.json.Створіть кореневий документ
Кореневий маршрут рендерить
<html>. Він зчитує необов'язковий параметр локалі для встановленняlangтаdir, щоб атрибути були коректними в згенерованому сервером HTML ще до запуску JavaScript.src/routes/__root.tsxКопіювати кодСкопіюйте код у буфер обміну
Створіть маршрут макета локалі
Папка
{-$locale}створює необов'язковий сегмент шляху:/aboutта/fr/aboutобидва відповідають/{-$locale}/about. Цей макет:- Відхиляє непідтримувані префікси (
/xx/about→ 404). - Завантажує простір імен
commonлише для поточної локалі. - Передає повідомлення через
IntlProvider.
Результат завантажувача серіалізується в HTML і повторно використовується під час гідратації, тому клієнт не завантажує
common.jsonудруге. ЗначенняstaleTime: Infinityкешує його між переходами на стороні клієнта.src/routes/{-$locale}/route.tsxКопіювати кодСкопіюйте код у буфер обміну
IntlProviderне об'єднує автоматично повідомлення від батьківського провайдера. Наступний крок додає невеликий компонент, який це робить, щоб кожна сторінка могла додавати власний простір імен поверхcommon.- Відхиляє непідтримувані префікси (
Ізолюйте повідомлення сторінок (Scoped Messages)
Кожна сторінка завантажує власний простір імен у своєму лоадері, а потім огортає свій вміст компонентом
ScopedMessages, який об'єднує простір імен сторінки з батьківськими повідомленнями.src/components/ScopedMessages.tsxКопіювати кодСкопіюйте код у буфер обміну
Використовуйте переклади на ваших сторінках
Лоадер сторінки отримує простір імен
aboutдля поточної локалі, функціяhead()формує на його основі перекладені та повні метадані SEO (дивіться крок 13), а компонент рендерить вміст.src/routes/{-$locale}/about.tsxКопіювати кодСкопіюйте код у буфер обміну
Використовуйте переклади та форматування в компонентах
Будь-який компонент під провайдерами може викликати
useTranslationsтаuseFormatter. Форми множини обробляються через ICU, а числа форматуються відповідно до активної локалі.src/components/Counter.tsxКопіювати кодСкопіюйте код у буфер обміну
Створіть компонент локалізованого посилання
Необов'язковоКожен маршрут знаходиться під
{-$locale}, тому посилання має містити поточний параметр локалі. Ця обгортка зберігає типізованийtoз TanStack Router та автоматично підставляє локаль за вас.src/components/LocalizedLink.tsxКопіювати кодСкопіюйте код у буфер обміну
src/components/Header.tsxКопіювати кодСкопіюйте код у буфер обміну
Змінюйте мову вашого контенту
Необов'язковоРендеріть перемикач як посилання, а не
<select>. Посилання доступні для пошукових роботів, що дозволяє їм знаходити кожну мовну версію, і вони працюють навіть без JavaScript.to="."зберігає поточну сторінку і лише замінює параметр локалі. Файл cookie зберігає явний вибір для middleware перенаправлення з кроку 16.src/components/LocaleSwitcher.tsxКопіювати кодСкопіюйте код у буфер обміну
Інтернаціоналізуйте ваші метадані
Необов'язковоОсь де i18n дає найбільшу перевагу: кожна мовна версія може ранжуватися окремо. Кожна сторінка має надавати:
- перекладені
<title>таdescription; - канонічну URL-адресу, яка вказує на саму себе (а не на локаль за замовчуванням);
- по одній альтернативі
hreflangна кожну локаль, плюсx-defaultдля непідтримуваних мов; - теги Open Graph
og:locale,og:locale:alternateтаog:url, які використовуються для попереднього перегляду в соцмережах; - JSON-LD із полем
inLanguage, що допомагає пошуковим системам та ШІ-асистентам точно визначати мову сторінки.
Єдина допоміжна функція формує все це разом, завдяки чому код сторінок залишається лаконічним:
src/i18n/seo.tsКопіювати кодСкопіюйте код у буфер обміну
Використовуйте її в
head()кожної сторінки, як показано на кроці 9. Для головної сторінки передайтеpath: "/".- перекладені
Інтернаціоналізуйте ваш sitemap
Необов'язковоБагатомовна карта сайту (sitemap) містить кожну URL-адресу кожної локалі, і кожен запис оголошує всі свої альтернативи за допомогою
xhtml:link. Google використовує ці анотації точно так само, як тегиhreflangна самій сторінці, що робить їх надійною страховкою для сторінок, які рідко скануються.Серверні маршрути TanStack Start дозволяють віддавати sitemap безпосередньо з файлового маршруту:
src/routes/sitemap[.]xml.tsКопіювати кодСкопіюйте код у буфер обміну
Інтернаціоналізуйте ваш robots.txt
Необов'язковоПриватні маршрути існують кожною мовою, тому правила
Disallowповинні охоплювати всі префікси. Видалітьpublic/robots.txt, якщо стартовий шаблон створив його, а потім віддавайте його з маршруту:src/routes/robots[.]txt.tsКопіювати кодСкопіюйте код у буфер обміну
Перенаправляйте нових відвідувачів на їхню мову
Необов'язковоMiddleware обробки запитів спрямовує відвідувача, який заходить на
/, на бажану мову, спираючись спершу на cookie локалі, а потім на заголовокAccept-Language. Перенаправляється лише/: глибокі посилання ніколи не змінюються, тому поширені URL та пошукові роботи завжди отримують саме ту сторінку, яку запитували.src/i18n/negotiateLocale.tsКопіювати кодСкопіюйте код у буфер обміну
src/start.tsКопіювати кодСкопіюйте код у буфер обміну
Відвідувач, який явно вибрав англійську в перемикачі, отримує
locale=enу cookie, тому його більше ніколи не перенаправлятиме. При повністю статичному деплої (крок 18)/віддається як файл і цей middleware не виконується, що цілком нормально: сторінка залишається доступною, а перемикач бере на себе решту.Збережіть API use-intl та скоротіть розмір runtime за допомогою Intlayer
Необов'язковоБенчмарк показує, що найважчою частиною налаштування use-intl є сам runtime (~76 KB gzip). Адаптер сумісності
@intlayer/use-intlнадає той самий API (useTranslations,useFormatter,IntlProvider,createTranslator, ICU множини,t.rich), але віддає дані зі скомпільованих словників Intlayer: ~6.7 KB замість ~75.9 KB, 0% витоку локалей та 0% витоку сторінок, без жодних змін у ваших компонентах.bashКопіювати кодСкопіюйте код у буфер обміну
Плагін Vite створює аліас з
use-intlна адаптер, тому наявні імпорти продовжують працювати без змін:vite.config.tsКопіювати кодСкопіюйте код у буфер обміну
Ваші файли JSON залишаються єдиним джерелом правди завдяки плагіну синхронізації JSON:
intlayer.config.tsКопіювати кодСкопіюйте код у буфер обміну
Адаптер також є плавним шляхом міграції: після його підключення ви можете переводити компоненти один за одним на нативний API
useIntlayer. Дивіться посібник з Intlayer для TanStack Start.Виконуйте пререндеринг кожної локалі
Необов'язковоСтатичний HTML - це найшвидша сторінка, яку ви можете віддати, і найпростіша для індексації. Перелічіть усі локалізовані шляхи, щоб TanStack Start виконав пререндеринг усіх мовних версій під час збірки, а також файлів sitemap та robots:
vite.config.tsКопіювати кодСкопіюйте код у буфер обміну
Оскільки перемикач локалей містить справжні посилання, параметр
crawlLinks: trueтакож автоматично виявляє сторінки, які ви могли забути додати до списку.Обробляйте локалізовані сторінки 404
Необов'язковоМакет з кроку 7 вже викликає
notFound()для невідомих префіксів локалей. Додайте маршрут catch-all, щоб невідомі шляхи всередині локалі також відображали локалізовану сторінку 404 та позначали її тегомnoindex: React 19 автоматично піднімає тег<meta>у<head>.src/components/NotFound.tsxКопіювати кодСкопіюйте код у буфер обміну
src/routes/{-$locale}/$.tsxКопіювати кодСкопіюйте код у буфер обміну
Отримуйте доступ до локалі в серверних функціях
Необов'язковоСерверні функції не отримують параметри маршруту. Зчитуйте cookie локалі з фолбеком на заголовок
Accept-Language, щоб надіслати локалізований лист або зберегти налаштування мови:src/server/getServerLocale.tsКопіювати кодСкопіюйте код у буфер обміну
Для перекладу всередині серверної функції комбінуйте це з
loadMessagesтаcreateTranslatorзuse-intl.Автоматизуйте ваші переклади за допомогою Intlayer
Необов'язковоuse-intl відображає переклади, але не допомагає вам їх створювати. Intlayer є безкоштовним інструментом із відкритим кодом, який закриває цю прогалину, навіть якщо ви продовжуєте використовувати use-intl:
- Тестуйте відсутні переклади в CI або юніт-тестах. Дивіться тестування перекладів.
- Перекладайте за допомогою ШІ, використовуючи власний API-ключ та провайдера: команда
npx intlayer fillперекладає відсутні ключі з урахуванням контексту вашого застосунку. Дивіться автозаповнення та CLI. - Зберігайте ваші файли JSON як джерело правди за допомогою плагіна синхронізації JSON.
- Редагуйте вміст візуально за допомогою візуального редактора та CMS, щоб нетехнічні спеціалісти могли оновлювати переклади.
- Надайте контекст вашому ШІ-агенту за допомогою MCP-сервера та навичок агентів.
- Скануйте ваш розгорнутий сайт на наявність відсутніх
hreflang, некоректних канонічних посилань та витоків локалей за допомогою команди scan.
Щоб ознайомитися з усіма можливостями, дивіться переваги Intlayer.
Часті запитання
Так, якщо вам потрібен API next-intl поза межами Next.js. Ви отримуєте повідомлення ICU, форматувальники та надійну підтримку TypeScript, уникаючи специфічних для Next.js обмежень, таких як setRequestLocale. Компромісом є вага: бенчмарк фіксує ~76 KB gzip для runtime, а при звичайному налаштуванні в браузер завантажуються всі локалі та всі сторінки. Завантажуйте простори імен за маршрутами та локалями, як показано в цьому посібнику, щоб уникнути витоків.
use-intl - це ядро next-intl. next-intl додає поверх нього інтеграції для Next.js: middleware, навігаційні хелпери, getTranslations для серверних компонентів та конфігурацію запитів. У TanStack Start ви використовуєте use-intl напряму та реалізуєте маршрутизацію через TanStack Router, як показано вище.
Використовуйте префікс в URL. У цьому випадку кожна мовна версія має власну URL-адресу, яку пошукові системи можуть індексувати, а користувачі - поширювати. Cookie все ще корисний для збереження явного вибору, що й робить middleware перенаправлення з кроку 16.
Сервер і браузер форматують дати в різних часових поясах. Передайте явний timeZone в IntlProvider (або часовий пояс відвідувача, збережений у cookie), щоб обидві сторони генерували однаковий текст.
По-перше, розділіть повідомлення за просторами імен і завантажуйте їх за маршрутами та локалями за допомогою import.meta.glob, що усуває витоки локалей і сторінок. Далі, якщо розмір runtime критичний, перейдіть на адаптер @intlayer/use-intl: той самий API, але ~6.7 KB замість ~75.9 KB за даними бенчмарку.
Викличте createTranslator всередині функції head() маршруту з повідомленнями, повернутими лоадером маршруту, а потім поверніть title, description, canonical та посилання hreflang. Крок 13 містить готовий допоміжний модуль.
Коментарі
Поки що немає коментарів. Будьте першим, хто поділиться своїми думками.
