Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту
Історія версій
- "Initial history"v9.1.306.08.2025
Вміст цієї сторінки перекладено за допомогою штучного інтелекту.
Переглянути останню версію оригінального вмісту англійськоюIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Перекладіть свій вебсайт SolidStart за допомогою Intlayer | Інтернаціоналізація (i18n)
Зміст
Цей посібник охоплює застосунок SolidStart із серверним рендерингом (SSR): виявлення локалі відбувається під час запиту, сторінки рендеряться на сервері відповідною мовою, а сигнали <html lang>, hreflang та карти сайту, необхідні пошуковим системам, формуються на боці сервера.
Чому Intlayer замість альтернатив?
У порівнянні з основними рішеннями, такими як @solid-primitives/i18n або i18next, Intlayer є рішенням зі вбудованими оптимізаціями, такими як:
Intlayer оптимізовано для ідеальної роботи з Solid, пропонуючи обмеження контенту на рівні компонентів, реактивні переклади та всі функції, необхідні для масштабування інтернаціоналізації (i18n).
Замість того, щоб завантажувати величезні файли JSON на свої сторінки, завантажуйте лише необхідний контент. Intlayer допомагає зменшити розмір бандлу та сторінок до 50%.
Обмеження контенту вашого застосунку спрощує обслуговування для великомасштабних застосунків. Ви можете дублювати або видаляти окрему папку функціоналу без когнітивного навантаження, пов'язаного з перевіркою всієї кодової бази контенту. Крім того, Intlayer повністю типізовано, щоб забезпечити точність вашого контенту.
Спільне розміщення контенту зменшує контекст, необхідний великим мовним моделям (LLM). Intlayer також постачається з набором інструментів, таких як CLI для перевірки відсутніх перекладів, LSP, MCP та навички агента, щоб зробити досвід розробки (DX) ще зручнішим для ШІ-агентів.
Використовуйте автоматизацію для перекладу у вашому CI/CD пайплайні за допомогою обраної LLM за вартістю вашого постачальника ШІ. Intlayer також пропонує компілятор для автоматизації вилучення контенту, а також веб-платформу для допомоги у перекладі у фоновому режимі.
Підключення величезних файлів JSON до компонентів може призвести до проблем із продуктивністю та реактивністю. Intlayer оптимізує завантаження контенту під час збірки.
Більше ніж просто рішення i18n, Intlayer надає візуальний редактор із власною хостинговою платформою та повноцінну CMS, щоб допомогти вам керувати багатомовним контентом у реальному часі, роблячи співпрацю з перекладачами, копірайтерами та іншими членами команди безперешкодною. Контент можна зберігати локально та/або віддалено.
Покроковий посібник із налаштування Intlayer у застосунку SolidStart
Встановіть залежності
Встановіть необхідні пакети за допомогою npm:
bashКопіювати кодСкопіюйте код у буфер обміну
npx intlayer init --interactiveПрапор
--interactiveє необов'язковим. Використовуйтеintlayer-cli init, якщо ви є ШІ-агентом.Ця команда виявить ваше середовище та встановить необхідні пакети. Наприклад:
bashКопіювати кодСкопіюйте код у буфер обміну
npm install intlayer solid-intlayer vite-intlayerintlayer
Основний пакет, який надає інструменти інтернаціоналізації для управління конфігурацією, перекладу, декларації контенту, транспіляції та команд CLI.
solid-intlayer
Пакет, який інтегрує Intlayer із застосунком Solid. Він надає провайдери контексту та хуки для інтернаціоналізації Solid.
vite-intlayer
Включає плагін Vite для інтеграції Intlayer із бандлером Vite, а також обробник маршрутизації локалей, який виявляє бажану локаль користувача, керує cookie та обробляє перенаправлення URL.
vite-intlayerтут є задачею серверної сторони, а не лише етапу збірки: він надає обробник запитів, який запускає сервер Nitro в SolidStart. Збереження його вdependenciesє безпечним рішенням за замовчуванням — ви можете перемістити його вdevDependenciesлише якщо ви деплоїте зібрану директорію.output, у яку Nitro вбудовує цей обробник.Конфігурація вашого проєкту
Створіть конфігураційний файл для налаштування мов вашого застосунку:
intlayer.config.tsКопіювати кодСкопіюйте код у буфер обміну
import { type IntlayerConfig, Locales } from "intlayer"; const config: IntlayerConfig = { internationalization: { locales: [ Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, // Ваші інші локалі ], defaultLocale: Locales.ENGLISH, }, routing: { mode: "prefix-no-default", }, }; export default config;При
prefix-no-defaultлокаль за замовчуванням обслуговується з URL-адрес без префікса:plaintextКопіювати кодСкопіюйте код у буфер обміну
/ /about → Англійська (локаль за замовчуванням)/fr /fr/about → Французька/es /es/about → ІспанськаЗа допомогою цього конфігураційного файлу ви можете налаштувати локалізовані URL-адреси, перенаправлення middleware, назви cookie, розташування та розширення ваших декларацій контенту, вимкнути логи Intlayer у консолі тощо. Повний список доступних параметрів дивіться в документації з конфігурації.
Інтегруйте Intlayer у вашу конфігурацію Vite
Додайте плагін Intlayer до вашої конфігурації:
vite.config.tsКопіювати кодСкопіюйте код у буфер обміну
import { solidStart } from "@solidjs/start/config"; import { nitro } from "nitro/vite"; import { defineConfig } from "vite"; import { intlayer } from "vite-intlayer"; export default defineConfig({ plugins: [solidStart(), nitro(), intlayer()], });Плагін Vite
intlayer()збирає ваші файли декларації контенту, відстежує їх у режимі розробки та визначає змінні середовища Intlayer усередині застосунку. Він також надає псевдоніми (aliases), які оптимізують продуктивність.Маршрутизація локалей поставляється разом із плагіном
SolidStart працює на Nitro, і
intlayer()реєструє свій обробник маршрутизації локалей безпосередньо в конвеєрі сервера Nitro (через опціюrouting.enableProxy, за замовчуваннямtrue). Більше нічого підключати не потрібно: на зібраному сервері кожен запит перевіряється до того, як він досягне маршрутизатора, і- локаль зчитується з префікса URL, потім із cookie
INTLAYER_LOCALE, потім із заголовкаAccept-Language; - URL-адреса без префікса перенаправляється на її локалізований аналог, якщо визначена локаль не є локаллю за замовчуванням (
/→/fr); - URL-адреса з надлишковим префіксом перенаправляється назад до канонічної форми (
/en/about→/about); - cookie локалі записується назад у відповідь.
- локаль зчитується з префікса URL, потім із cookie
Оголосіть свій контент
Створюйте та керуйте деклараціями контенту для зберігання перекладів:
src/contents/home.content.tsКопіювати кодСкопіюйте код у буфер обміну
import { type Dictionary, t } from "intlayer"; const homeContent = { key: "home-page", content: { title: t({ en: "Hello world!", fr: "Bonjour le monde !", es: "¡Hola mundo!", }), metaTitle: "SolidStart + Intlayer", metaDescription: t({ en: "A SolidStart application internationalized with Intlayer.", fr: "Une application SolidStart internationalisée avec Intlayer.", es: "Una aplicación SolidStart internacionalizada con Intlayer.", }), documentation: t({ en: "Visit start.solidjs.com to learn how to build SolidStart apps.", fr: "Visitez start.solidjs.com pour apprendre à créer des applications SolidStart.", es: "Visita start.solidjs.com para aprender a crear aplicaciones SolidStart.", }), }, } satisfies Dictionary; export default homeContent;⚠️ Особливість SolidStart: кожен файл
.ts/.tsxуsrc/routesстає маршрутом, а файл.content.tsмає експорт за замовчуванням, тому він підхоплюється як сторінка. Зберігайте декларації контенту ваших сторінок за межами директорії routes (src/contents/чудово підходить). Контент компонентів може залишатися поруч, оскількиsrc/componentsне сканується файловим маршрутизатором.Ваші декларації контенту можуть бути визначені в будь-якому місці застосунку, якщо вони включені до директорії
contentDir(за замовчуванням./src) і відповідають розширенню файлів декларації контенту (за замовчуванням.content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).Для отримання детальнішої інформації зверніться до документації з декларації контенту.
Додайте локалізовану маршрутизацію
Метою цього кроку є надати кожній мові власну URL-адресу, яку індексують пошукові системи.
Перемістіть свої сторінки під необов'язковий динамічний сегмент. У файловому маршрутизаторі SolidStart
[[locale]]компілюється у шаблон шляху:locale?:plaintextКопіювати кодСкопіюйте код у буфер обміну
src/routes/ [[locale]].tsx ← макет, який перевіряє сегмент [[locale]]/ index.tsx → / та /fr та /es about.tsx → /about та /fr/about та /es/about [...404].tsx → загальний файл для всього іншогоЄдина задача файлу макета (layout) — обмежити сегмент налаштованою локаллю:
src/routes/[[locale]].tsxКопіювати кодСкопіюйте код у буфер обміну
import type { RouteSectionProps } from "@solidjs/router";import { locales } from "intlayer";export const route = { matchFilters: { locale: locales, },};export default function LocaleLayout(props: RouteSectionProps) { return <>{props.children}</>;}@solidjs/routerрозгортає:locale?у два шаблони — один із сегментом і один без нього — і пробує їх у порядку спадання специфічності.matchFilters— це те, що відрізняє працююче налаштування від заплутаного:Показати весь вміст таблиціВідкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
URL Без matchFiltersЗ matchFilters/fr/aboutФранцузька сторінка "Про нас" Французька сторінка "Про нас" /aboutСторінка "Про нас" (статичний сегмент перемагає) Сторінка "Про нас" /unknownГоловна сторінка, тихо, з locale=unknownНемає збігу → переходить до загального 404 Віддавайте перевагу
[locale](обов'язковий) замість[[locale]], якщо ви використовуєте режим маршрутизації'prefix-all', і повністю вилучіть сегмент для'no-prefix'або'search-params'.Передайте локаль у свій застосунок
URL-адреса є єдиним джерелом правди для локалі: middleware вже перенаправив запит на локалізований шлях, тому зчитування шляху в кореневому макеті зберігає узгодженість серверного рендерингу та гідратації на боці клієнта і робить так, що кожна навігація на боці клієнта оновлює локаль автоматично.
src/app.tsxКопіювати кодСкопіюйте код у буфер обміну
import { MetaProvider } from "@solidjs/meta";import { Router, useLocation } from "@solidjs/router";import { FileRoutes } from "@solidjs/start/router";import { defaultLocale, getHTMLTextDir, getLocaleFromPath } from "intlayer";import { IntlayerProvider } from "solid-intlayer";import { createEffect, type ParentProps, Suspense } from "solid-js";import { isServer } from "solid-js/web";import { Nav } from "~/components/Nav";import "./app.css";const RootLayout = (props: ParentProps) => { const location = useLocation(); const locale = () => getLocaleFromPath(location.pathname) ?? defaultLocale; // Сервер рендерить <html> у entry-server.tsx; навігація на боці клієнта // між локалями повинна оновлювати атрибути самостійно. createEffect(() => { if (isServer) return; document.documentElement.lang = locale(); document.documentElement.dir = getHTMLTextDir(locale()); }); return ( <MetaProvider> <IntlayerProvider locale={locale()}> <Nav /> <Suspense>{props.children}</Suspense> </IntlayerProvider> </MetaProvider> );};export default function App() { return ( <Router root={RootLayout}> <FileRoutes /> </Router> );}IntlayerProviderреагує на свій пропlocale, тому передачі виклику аксесораlocale()усередині JSX достатньо — Solid компілює його в гетер, і все дерево повторно рендериться новою мовою під час зміни URL.Встановіть атрибути lang та dir елемента HTML на сервері
Елемент
<html>рендериться за допомогоюentry-server.tsx, за межамиRouter. Замість цього зчитайте локаль із URL запиту:src/entry-server.tsxКопіювати кодСкопіюйте код у буфер обміну
// @refresh reloadimport { createHandler, StartServer } from "@solidjs/start/server";import { defaultLocale, getHTMLTextDir, getLocaleFromPath } from "intlayer";import { getRequestEvent } from "solid-js/web";export default createHandler(() => ( <StartServer document={({ assets, children, scripts }) => { const url = getRequestEvent()?.request.url ?? "/"; const locale = getLocaleFromPath(url) ?? defaultLocale; return ( <html dir={getHTMLTextDir(locale)} lang={locale}> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> {assets} </head> <body> <div id="app">{children}</div> {scripts} </body> </html> ); }} />));Пошукові роботи тепер отримують правильну мову з першого байта:
htmlКопіювати кодСкопіюйте код у буфер обміну
<html dir="ltr" lang="fr"></html>Використовуйте Intlayer у своїх сторінках
Отримуйте доступ до своїх словників контенту по всьому застосунку:
src/routes/[[locale]]/index.tsxКопіювати кодСкопіюйте код у буфер обміну
import { Meta, Title } from "@solidjs/meta";import { useIntlayer } from "solid-intlayer";import Counter from "~/components/Counter";export default function Home() { const content = useIntlayer("home-page"); return ( <main> <Title>{content.metaTitle.value}</Title> <Meta content={content.metaDescription.value} name="description" /> <h1>{content.title}</h1> <Counter /> <p>{content.documentation}</p> </main> );}У Solid
useIntlayerповертає реактивний контент (наприклад,content). Ви можете звертатися до його властивостей напряму.Якщо ви хочете використовувати свій контент у строковому атрибуті (
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)}" />Щоб дізнатися більше про хук
useIntlayer, зверніться до документації.Вузли контенту не обмежуються простими перекладами. Наприклад, лічильник з множиною:
src/components/Counter.content.tsКопіювати кодСкопіюйте код у буфер обміну
import { type Dictionary, plural, t } from "intlayer";const counterContent = { key: "counter", content: { clicks: plural({ one: t({ en: "{{count}} click", fr: "{{count}} clic", es: "{{count}} clic", }), other: t({ en: "{{count}} clicks", fr: "{{count}} clics", es: "{{count}} clics", }), }), },} satisfies Dictionary;export default counterContent;src/components/Counter.tsxКопіювати кодСкопіюйте код у буфер обміну
import { useIntlayer } from "solid-intlayer";import { createSignal } from "solid-js";export default function Counter() { const [count, setCount] = createSignal(0); const content = useIntlayer("counter"); return ( <button onClick={() => setCount(count() + 1)} type="button"> {content.clicks(count())} </button> );}plural()вибирає категорію за допомогоюIntl.PluralRulesдля активної локалі, тому мови з більше ніж двома формами множини працюють без додаткового коду.Створіть компонент локалізованого посилання
Створіть власний компонент
Link, який автоматично додає префікс поточної мови до внутрішніх URL-адрес:src/components/LocalizedLink.tsxКопіювати кодСкопіюйте код у буфер обміну
import { A, type AnchorProps } from "@solidjs/router";import { getLocalizedUrl } from "intlayer";import { useLocale } from "solid-intlayer";import type { ParentComponent } from "solid-js";export const LocalizedLink: ParentComponent<AnchorProps> = (props) => { const { locale } = useLocale(); const isExternal = () => /^[a-z][a-z0-9+.-]*:/i.test(props.href); const localizedHref = () => isExternal() ? props.href : getLocalizedUrl(props.href, locale()); return <A {...props} href={localizedHref()} />;};src/components/Nav.tsxКопіювати кодСкопіюйте код у буфер обміну
import { useIntlayer } from "solid-intlayer";import type { Component } from "solid-js";import { LocaleSwitcher } from "./LocaleSwitcher";import { LocalizedLink } from "./LocalizedLink";export const Nav: Component = () => { const content = useIntlayer("nav"); return ( <nav> <LocalizedLink href="/">{content.home}</LocalizedLink> <LocalizedLink href="/about">{content.about}</LocalizedLink> <LocaleSwitcher /> </nav> );};Написання
href="/about"один раз тепер створює/about,/fr/aboutабо/es/aboutзалежно від активної локалі — без ручного додавання префіксів ніде на ваших сторінках.Створіть компонент перемикача локалей
Рендеріть перемикач як справжні посилання (anchors) замість
<select>: кожна мова поточної сторінки стає посиланням для індексації, яке можна відкрити в новій вкладці, чого не може забезпечити елемент керування лише на JavaScript.getPathWithoutLocaleвидаляє сегмент локалі з поточного шляху, аgetLocalizedUrlвідновлює його для цільової локалі, тому посилання слідують вашому режиму маршрутизації без жорсткого кодування будь-чого. Навігація — це те, що змінює відрендерену локаль — маршрут[[locale]]отримує її з URL, — тоді якsetLocaleзберігає вибір у cookieINTLAYER_LOCALE, щоб наступний візит на URL-адресу без локалі отримував ту саму мову.src/components/LocaleSwitcher.tsxКопіювати кодСкопіюйте код у буфер обміну
import { A, useLocation } from "@solidjs/router"; import { getHTMLTextDir, getLocaleName, getLocalizedUrl, getPathWithoutLocale, } from "intlayer"; import { useIntlayer, useLocale } from "solid-intlayer"; import { type Component, For } from "solid-js"; export const LocaleSwitcher: Component = () => { const content = useIntlayer("locale-switcher"); const location = useLocation(); const { locale, setLocale, availableLocales } = useLocale(); // Канонічний шлях (без локалі) сторінки, яка відображається в даний момент const pathWithoutLocale = () => getPathWithoutLocale(location.pathname); return ( <div> <button aria-label={content.label.value} popoverTarget="localePopover" type="button" > {getLocaleName(locale())} </button> <div id="localePopover" popover="auto"> <For each={availableLocales}> {(localeItem) => ( <A dir={getHTMLTextDir(localeItem)} // Лише точний збіг, щоб посилання локалі за замовчуванням не позначалося // як активне на кожній сторінці end href={getLocalizedUrl(pathWithoutLocale(), localeItem)} hreflang={localeItem} lang={localeItem} onClick={() => setLocale(localeItem)} // Гарантує, що кнопка "назад" у браузері повертає на попередню сторінку replace > {/* Мова власною локаллю - наприклад, Français */} {getLocaleName(localeItem)} </A> )} </For> </div> </div> ); };У Solid
localeзuseLocaleє аксесором сигналу. Використовуйтеlocale()(з дужками), щоб реактивно зчитувати його поточне значення.getLocaleName(localeItem)рендерить кожну мову її власною мовою —English / Français / Español. Передайте другий аргумент, щоб перекласти назви мовою, яка відображається в даний момент:getLocaleName(localeItem, locale())даєEnglish / French / Spanishанглійською,anglais / français / espagnolфранцузькою.<A>вже встановлюєaria-current="page"на посиланні, що відповідає поточному URL, тому для цього нічого додавати не потрібно.replaceзчитується з відрендереного атрибута маршрутизатором: він замінює запис в історії замість додавання нового, тому кнопка "назад" у браузері повертає на сторінку, відвідану до перемикання, а не на ту саму сторінку попередньою мовою.dirтаhreflangна кожному посиланні забезпечують правильне орієнтування назв мов із написанням справа наліво та повідомляють допоміжним технологіям і пошуковим роботам, на яку мову вказує кожне посилання.Щоб дізнатися більше про хук
useLocale, зверніться до документації.Сформуйте посилання canonical та hreflang
Необов'язковоАннотації
hreflangповідомляють пошуковим системам, що/about,/fr/aboutта/es/about— це одна й та сама сторінка різними мовами.getMultilingualUrlsотримує їх із канонічного шляху (без локалі), дотримуючись вашого режиму маршрутизації, тому нічого не закомпільовано жорстко:src/components/AlternateLinks.tsxКопіювати кодСкопіюйте код у буфер обміну
import { defaultLocale, getMultilingualUrls, getPathWithoutLocale,} from "intlayer";import { type Component, For } from "solid-js";export type AlternateLinksProps = { /** Абсолютний URL сторінки, що рендериться. */ url: string;};export const AlternateLinks: Component<AlternateLinksProps> = (props) => { const multilingualUrls = () => { const { origin, pathname } = new URL(props.url); return Object.entries( getMultilingualUrls(`${origin}${getPathWithoutLocale(pathname)}`) ); }; const canonicalUrl = () => new URL(props.url).origin + new URL(props.url).pathname; return ( <> <link href={canonicalUrl()} rel="canonical" /> <For each={multilingualUrls()}> {([locale, localizedUrl]) => ( <link href={localizedUrl} hreflang={locale} rel="alternate" /> )} </For> <link href={ multilingualUrls().find(([locale]) => locale === defaultLocale)?.[1] } hreflang="x-default" rel="alternate" /> </> );};Відрендеріть це у заголовку документа (head), де доступний URL запиту:
src/entry-server.tsxКопіювати кодСкопіюйте код у буфер обміну
import { AlternateLinks } from "~/components/AlternateLinks";// … усередині <head>, поруч з іншими мета-тегами:<AlternateLinks url={url} />;GET /fr/aboutпотім віддає:htmlКопіювати кодСкопіюйте код у буфер обміну
<link href="https://example.com/fr/about" rel="canonical" /><link href="https://example.com/about" hreflang="en" rel="alternate" /><link href="https://example.com/fr/about" hreflang="fr" rel="alternate" /><link href="https://example.com/es/about" hreflang="es" rel="alternate" /><link href="https://example.com/about" hreflang="x-default" rel="alternate" />Примітка щодо
@solidjs/meta: на момент написання,<Title>та<Meta>з@solidjs/metaзастосовуються на боці клієнта після гідратації, але не виводяться у серверний<head>у SolidStart v2. Доки це не буде виправлено вище за течією, рендеріть теги, які пошукові роботи повинні бачити без JavaScript —canonical,hreflang, і за потребиtitle/description— безпосередньо вentry-server.tsx, як показано вище.Обробіть незнайдені сторінки (404)
Необов'язковоМаршрут-заглушка (splat route) у корені
src/routesперехоплює кожен шлях, який не збігся із сегментом локалі — включаючи недійсні префікси локалей, відхиленіmatchFilters. Оскільки локаль усе ще надходить з URL через кореневий макет, сторінка 404 відображається мовою відвідувача:src/routes/[...404].tsxКопіювати кодСкопіюйте код у буфер обміну
import { Title } from "@solidjs/meta";import { HttpStatusCode } from "@solidjs/start";import { useIntlayer } from "solid-intlayer";import { LocalizedLink } from "~/components/LocalizedLink";export default function NotFound() { const content = useIntlayer("not-found-page"); return ( <main> <Title>{content.metaTitle.value}</Title> <HttpStatusCode code={404} /> <h1>{content.title}</h1> <LocalizedLink href="/">{content.backHome}</LocalizedLink> </main> );}Показати весь вміст таблиціВідкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
Запит Результат /xx404—xxне є налаштованою локаллю/nonexistent404локаллю за замовчуванням/fr/nonexistent404французькою мовою (Page introuvable)Згенеруйте багатомовну карту сайту (sitemap)
Необов'язковоГенератор карти сайту Intlayer розгортає кожен шлях у один запис для кожної локалі та з'єднує альтернативи
xhtml:linkміж ними, тому маршруту потрібно лише перелічити канонічні шляхи без локалі.На відміну от базових генераторів, які видають лише плоскі URL-адреси, Intlayer пов'язує двонаправлені посилання між кожним локалізованим варіантом кожної сторінки, що допомагає пошуковим системам пов'язувати локалізовані URL-адреси та подавати потрібну правильній аудиторії.
SolidStart перетворює файл, що експортує метод HTTP, у маршрут API і видаляє розширення
.tsзі шляху — томуsrc/routes/sitemap.xml.tsобслуговується за адресою/sitemap.xml:src/routes/sitemap.xml.tsКопіювати кодСкопіюйте код у буфер обміну
import type { APIEvent } from "@solidjs/start/server"; import { generateSitemap } from "intlayer"; const SITE_URL = process.env.SITE_URL ?? "http://localhost:3000"; export const GET = (_event: APIEvent) => { const sitemap = generateSitemap( [ { path: "/", changefreq: "daily", priority: 1.0 }, { path: "/about", changefreq: "monthly", priority: 0.8 }, ], { siteUrl: SITE_URL } ); return new Response(sitemap, { headers: { "Content-Type": "application/xml" }, }); };output of GET /sitemap.xmlКопіювати кодСкопіюйте код у буфер обміну
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <url> <loc>https://example.com/about</loc> <changefreq>monthly</changefreq> <priority>0.8</priority> <xhtml:link rel="alternate" hreflang="en" href="https://example.com/about"/> <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/about"/> <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/about"/> <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/about"/> </url></urlset>Маршрути API не підтримують необов'язкові параметри, тому зберігайте цей файл у корені
src/routes, за межами сегмента[[locale]]. Карта сайту вже містить кожну локаль.Ви можете побудувати
robots.txtтаким самим чином за допомогоюgetMultilingualUrls, щоб записиDisallowпокривали кожне локалізоване написання чутливого шляху:src/routes/robots.txt.tsКопіювати кодСкопіюйте код у буфер обміну
import { getMultilingualUrls } from "intlayer"; const SITE_URL = process.env.SITE_URL ?? "http://localhost:3000"; const disallowedPaths = ["/admin", "/private"].flatMap((path) => Object.values(getMultilingualUrls(path)) ); export const GET = () => new Response( [ "User-agent: *", "Allow: /", ...disallowedPaths.map((path) => `Disallow: ${path}`), "", `Sitemap: ${SITE_URL}/sitemap.xml`, ].join("\n"), { headers: { "Content-Type": "text/plain" } } );Отримайте локаль у ваших серверних функціях
Необов'язковоВи можете захотіти отримати доступ до поточної локалі зсередини серверної функції або маршруту API.
У налаштуванні на основі префіксів, такому як це, URL-адреса є авторитетною:
getLocaleFromPathзчитує префікс з URL запиту.getLocale— це запасний варіант для запитів, які не несуть префікса локалі — він перевіряє cookieINTLAYER_LOCALE, потім заголовокx-intlayer-locale, а потім узгоджуєAccept-Language.src/routes/[[locale]]/index.tsxКопіювати кодСкопіюйте код у буфер обміну
import { createAsync } from "@solidjs/router";import { getCookie, getIntlayer, getLocale, getLocaleFromPath } from "intlayer";import { getRequestEvent } from "solid-js/web";const loadLocalizedData = async () => { "use server"; const request = getRequestEvent()?.request; const locale = getLocaleFromPath(request?.url) ?? (await getLocale({ // Отримує cookie із запиту (за замовчуванням: 'INTLAYER_LOCALE') getCookie: (name) => getCookie(name, request?.headers.get("cookie") ?? ""), // Отримує заголовок із запиту (за замовчуванням: 'x-intlayer-locale'), // повертаючись до узгодження Accept-Language getHeader: (name) => request?.headers.get(name) ?? undefined, })); // Отримайте деякий контент поза компонентом за допомогою getIntlayer() const content = getIntlayer("home-page", locale); return { locale, title: String(content.title) };};export default function Page() { const data = createAsync(() => loadLocalizedData()); return <p>{data()?.title}</p>;}Не покладайтеся тут лише на
getLocale: cookie локалі записується лише тоді, коли відвідувач активно змінює мову, тому перший візит на/fr/...буде вирішуватися до локалі за замовчуванням.Вилучіть контент ваших компонентів
Необов'язковоЯкщо у вас є існуюча кодова база, перетворення тисяч файлів може зайняти багато часу.
Щоб спростити цей процес, 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Перемістіть згенеровані файли контенту ваших сторінок за межі
src/routesпісля цього з причини, поясненої на кроці 5.Налаштуйте TypeScript
Intlayer використовує розширення модулів (module augmentation), щоб отримати переваги TypeScript та зробити вашу кодову базу міцнішою.
Переконайтеся, що ваша конфігурація TypeScript включає автозгенеровані типи:
tsconfig.jsonКопіювати кодСкопіюйте код у буфер обміну
{ compilerOptions: { // ... ваші існуючі конфігурації }, include: [ "src", "*.ts", ".intlayer/**/*.ts", // Включити автозгенеровані типи ],}Ключі словника та шляхи до контенту тепер перевіряються під час компіляції:
tsxКопіювати кодСкопіюйте код у буфер обміну
useIntlayer("home-page"); // ✅useIntlayer("hom-page"); // ❌ Argument of type '"hom-page"' is not assignable to parameter of type 'keyof __DictionaryRegistry'
Перевірка вашого налаштування
Зберіть та запустіть сервер, а потім перевірте, чи ці запити поводяться належним чином:
Скопіюйте код у буфер обміну
npm run buildnode .output/server/index.mjsВідкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| Запит | Очікувана відповідь |
|---|---|
GET / | 200 — Англійська мова |
GET / з Accept-Language: fr | 302 → /fr |
GET / з cookie INTLAYER_LOCALE=es | 302 → /es |
GET /fr | 200 — Французька мова, <html lang="fr"> |
GET /fr/about | 200 — Французька сторінка "Про нас" |
GET /en/about | 302 → /about (канонічне перенаправлення) |
GET /xx | 404 |
GET /fr/nonexistent | 404 французькою мовою |
GET /sitemap.xml | 200 — багатомовна карта сайту XML |
Рядки, які рендерять сторінку, поводяться ідентично під vite dev. Три рядки перенаправлення застосовуються лише до зібраного сервера, якщо ви не зареєструєте обробник як middleware самостійно — дивіться крок 3.
Запускайте сервер розробки на Node (vite dev), а не на Bun (bun --bun vite dev): SSR у SolidStart наразі не працює під середовищем виконання Bun із помилкоюExpected a Response object, but received 'NodeResponse'. Це не пов'язано з Intlayer — це відтворюється на звичайному шаблоні — і впливає лише на сервер розробки, а не наvite build.
Конфігурація Git
Рекомендується ігнорувати файли, згенеровані Intlayer. Це дозволяє уникнути їх закоммічування у ваш Git-репозиторій.
Для цього ви можете додати наступні інструкції до вашого файлу .gitignore:
Скопіюйте код у буфер обміну
# Ігнорувати файли, згенеровані Intlayer.intlayerРозширення VS Code
Щоб покращити свій досвід розробки з Intlayer, ви можете встановити офіційне Розширення Intlayer для VS Code.
Встановити з VS Code Marketplace
Це розширення надає:
- Автодоповнення для ключів перекладу.
- Виявлення помилок у реальному часі для відсутніх перекладів.
- Вбудований (inline) перегляд перекладеного контенту.
- Швидкі дії для легкого створення та оновлення перекладів.
Поглиблення
Щоб піти далі, ви можете впровадити візуальний редактор або винести свій контент назовні за допомогою CMS.