使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
版本历史
- "更新 Solid useIntlayer API 用法以直接访问属性"v8.9.02026/5/4
- "添加 init 命令"v7.5.92025/12/30
- "初始化历史记录"v7.1.102025/11/20
此页面的内容已使用 AI 翻译。
查看英文原文的最新版本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
使用 Intlayer 翻译您的 SvelteKit 网站 | 国际化 (i18n)
目录
为什么选择 Inlayer 而不是替代品?
与“svelte-i18n”或“i18next”等主要解决方案相比,Intlayer是一个具有集成优化的解决方案,例如:
完整的 SvelteKit 覆盖
Intlayer 经过优化,可与 SvelteKit 完美配合,提供多语言路由、SSR 支持以及扩展国际化 (i18n) 所需的所有功能。
捆绑尺寸
不要将大量 JSON 文件加载到页面中,而只需加载必要的内容。 Intlayer 有助于将捆绑包和页面大小减少多达 50%。
可维护性
确定应用程序内容的范围有利于大型应用程序的维护。您可以复制或删除单个功能文件夹,而无需承担检查整个内容代码库的精神负担。此外,Intlayer 具有完全类型化 (fully typed),以确保您的内容的准确性。
人工智能代理
共置内容减少大型语言模型 (LLM) 所需的上下文。 Intlayer 还附带了一套工具,例如用于测试缺失翻译的 CLI、LSP、MCP 和 agent技能,使 AI 代理的开发者体验 (DX) 更加流畅。
自动化
使用您选择的法学硕士,通过自动化在 CI/CD 管道中进行翻译,而费用由您的 AI 提供商承担。 Intlayer 还提供了一个编译器来自动提取内容,以及一个网络平台来帮助在后台翻译。
表现
将大量 JSON 文件连接到组件可能会导致性能和反应性问题。 Intlayer 可在构建时 (build time)优化您的内容加载。
无需开发即可扩展
Intlayer 不仅仅是一个 i18n 解决方案,还提供了一个自托管的可视化编辑器和一个完整的 CMS 来帮助您管理多语言内容实时,与译员、文案人员和其他团队成员无缝协作。内容可以本地和/或远程存储。
在 SvelteKit 应用中设置 Intlayer 的分步指南
查看 GitHub 上的应用模板。
要开始,创建一个新的 SvelteKit 项目。以下是我们将创建的最终结构:
复制代码到剪贴板
.├── intlayer.config.ts├── package.json├── src│ ├── app.d.ts│ ├── app.html│ ├── hooks.server.ts│ ├── lib│ │ ├── getLocale.ts│ │ ├── LocaleSwitcher.svelte│ │ └── LocalizedLink.svelte│ ├── params│ │ └── locale.ts│ └── routes│ ├── [[locale=locale]]│ │ ├── +layout.svelte│ │ ├── +layout.ts│ │ ├── +page.svelte│ │ ├── +page.ts│ │ ├── about│ │ │ ├── +page.svelte│ │ │ ├── +page.ts│ │ │ └── page.content.ts│ │ ├── Counter.content.ts│ │ ├── Counter.svelte│ │ ├── Header.content.ts│ │ ├── Header.svelte│ │ ├── home.content.ts│ │ └── layout.content.ts│ ├── +layout.svelte│ └── layout.css├── static│ ├── favicon.svg│ └── robots.txt├── svelte.config.js├── tsconfig.json└── vite.config.ts安装依赖项
使用 npm 安装必要的包:
bash复制代码复制代码到剪贴板
npx intlayer init --interactive--interactive标志是可选的。如果你是 AI 代理,请使用intlayer-cli init。此命令将检测你的环境并安装所需的包。例如:
bash复制代码复制代码到剪贴板
npm install intlayer svelte-intlayernpm install vite-intlayer --save-dev- intlayer:核心 i18n 包。
- svelte-intlayer:为 Svelte/SvelteKit 提供上下文提供者和 store。
- vite-intlayer:Vite 插件,用于将内容声明与构建过程集成。
配置你的项目
在项目根目录创建一个配置文件:
intlayer.config.ts复制代码复制代码到剪贴板
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, },};export default config;在 Vite 配置中集成 Intlayer
更新你的
vite.config.ts以包含 Intlayer 插件。此插件处理你的内容文件的转译。vite.config.ts复制代码复制代码到剪贴板
import { sveltekit } from "@sveltejs/kit/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({ plugins: [intlayer(), sveltekit()], // 顺序很重要,Intlayer 应放在 SvelteKit 之前});声明你的内容
在你的
src文件夹的任何地方创建内容声明文件(例如src/lib/content或在你的组件旁边)。这些文件使用t()函数为每个语言环境定义应用的可翻译内容。在你的组件中使用 Intlayer
现在你可以在任何 Svelte 组件中使用
useIntlayer函数。它返回一个响应式 store,在语言环境改变时自动更新。该函数将自动遵守当前的语言环境(在 SSR 和客户端导航期间)。注意:
useIntlayer返回一个 Svelte store,因此你需要使用$前缀来访问其响应式值(例如$content.title)。src/lib/components/Component.svelte复制代码复制代码到剪贴板
<script lang="ts"> import { useIntlayer } from "svelte-intlayer"; // "hero-section" 对应于第 4 步中定义的 key const content = useIntlayer("hero-section");</script><!-- 将内容呈现为简单内容 --><h1>{$content.title}</h1><!-- 使用编辑器呈现可编辑的内容 --><h1>{@const Title = $content.title}<Title /></h1><!-- 将内容呈现为字符串 --><div aria-label={$content.title.value}></div><div aria-label={$content.title.toString()}></div><div aria-label={String($content.title)}></div>设置路由
可选以下步骤展示如何在 SvelteKit 中设置基于语言环境的路由。这允许你的 URL 包含语言环境前缀(例如
/en/about、/fr/about),以获得更好的 SEO 和用户体验。bash复制代码复制代码到剪贴板
.└─── src ├── app.d.ts # 定义语言环境类型 ├── hooks.server.ts # 管理语言环境路由 ├── lib │ └── getLocale.ts # 从 header、cookies 检查语言环境 ├── params │ └── locale.ts # 定义语言环境参数 └── routes ├── [[locale=locale]] # 用路由组包装以设置语言环境 │ ├── +layout.svelte # 路由的本地布局 │ ├── +layout.ts │ ├── +page.svelte │ ├── +page.ts │ └── about │ ├── +page.svelte │ └── +page.ts └── +layout.svelte # 用于字体和全局样式的根布局处理服务器端语言环境检测
在 SvelteKit 中,服务器需要知道用户的语言环境以在 SSR 期间呈现正确的内容。我们使用
hooks.server.ts从 URL 或 cookies 检测语言环境。创建或修改
src/hooks.server.ts:src/hooks.server.ts复制代码复制代码到剪贴板
import type { Handle } from "@sveltejs/kit";import { getLocalizedUrl } from "intlayer";import { getLocale } from "$lib/getLocale";export const handle: Handle = async ({ event, resolve }) => { const detectedLocale = getLocale(event); // 检查当前路径是否已以语言环境开头(例如 /fr、/en) const pathname = event.url.pathname; const targetPathname = getLocalizedUrl(pathname, detectedLocale); // 如果 URL 中没有语言环境(例如用户访问 "/"),则重定向他们 if (targetPathname !== pathname) { return new Response(undefined, { headers: { Location: targetPathname }, status: 307, // 临时重定向 }); } return resolve(event, { transformPageChunk: ({ html }) => html.replace("%lang%", detectedLocale), });};然后,创建一个 helper 来从请求事件获取用户的语言环境:
src/lib/getLocale.ts复制代码复制代码到剪贴板
import { configuration, getLocaleFromStorage, localeDetector, type Locale,} from "intlayer";import type { RequestEvent } from "@sveltejs/kit";/** * 从请求事件获取用户的语言环境。 * 此函数在 `src/hooks.server.ts` 中的 `handle` hook 中使用。 * * 它首先尝试从 Intlayer storage(cookies 或自定义 headers)获取语言环境。 * 如果找不到语言环境,它会回退到浏览器的 "Accept-Language" 协商。 * * @param event - 来自 SvelteKit 的请求事件 * @returns 用户的语言环境 */export const getLocale = (event: RequestEvent): Locale => { const defaultLocale = configuration?.internationalization?.defaultLocale; // 尝试从 Intlayer storage(Cookies 或 headers)获取语言环境 const storedLocale = getLocaleFromStorage({ // SvelteKit cookies 访问 getCookie: (name: string) => event.cookies.get(name) ?? null, // SvelteKit headers 访问 getHeader: (name: string) => event.request.headers.get(name) ?? null, }); if (storedLocale) { return storedLocale; } // 回退到浏览器 "Accept-Language" 协商 const negotiatorHeaders: Record<string, string> = {}; // 将 SvelteKit Headers 对象转换为普通的 Record<string, string> event.request.headers.forEach((value, key) => { negotiatorHeaders[key] = value; }); // 从 `Accept-Language` header 检查语言环境 const userFallbackLocale = localeDetector(negotiatorHeaders); if (userFallbackLocale) { return userFallbackLocale; } // 如果未找到匹配项,返回默认语言环境 return defaultLocale;};getLocaleFromStorage将根据你的配置从 header 或 cookie 检查语言环境。有关更多详情,请参阅配置。localeDetector函数将处理Accept-Languageheader 并返回最佳匹配。如果语言环境未配置,我们想返回 404 错误。为了简化这一点,我们可以创建一个
match函数来检查语言环境是否有效:/src/params/locale.ts复制代码复制代码到剪贴板
import { defaultLocale, locales, type Locale } from "intlayer";export const match = (param: Locale = defaultLocale): boolean => locales.includes(param);注意: 确保你的
src/app.d.ts包含语言环境定义:typescript复制代码复制代码到剪贴板
declare global { namespace App { interface Locals { locale: import("intlayer").Locale; } }}对于
+layout.svelte文件,我们可以删除所有内容,只保留与 i18n 无关的静态内容:src/+layout.svelte复制代码复制代码到剪贴板
<script lang="ts"> import './layout.css'; let { children } = $props();</script><div class="app"> {@render children()}</div><style> .app { /* */ }</style>然后,在
[[locale=locale]]组下创建一个新页面和布局:src/routes/[[locale=locale]]/+layout.ts复制代码复制代码到剪贴板
import type { Load } from "@sveltejs/kit";import { defaultLocale, type Locale } from "intlayer";export const prerender = true;// 使用通用 Load 类型export const load: Load = ({ params }) => { const locale: Locale = (params.locale as Locale) ?? defaultLocale; return { locale, };};src/routes/[[locale=locale]]/+layout.svelte复制代码复制代码到剪贴板
<script lang="ts"> import type { Snippet } from 'svelte'; import { useIntlayer, setupIntlayer } from "svelte-intlayer"; import Header from './Header.svelte'; import type { LayoutData } from './$types'; let { children, data }: { children: Snippet, data: LayoutData } = $props(); // 使用路由中的语言环境初始化 Intlayer $effect(() => { setupIntlayer(data.locale); }); // 使用布局内容字典 const layoutContent = useIntlayer('layout');</script><Header /><main> {@render children()}</main><footer> <p> {$layoutContent.footer.prefix.value}{' '} <a href="https://svelte.dev/docs/kit">{$layoutContent.footer.linkLabel.value}</a>{' '} {$layoutContent.footer.suffix.value} </p></footer><style> /* */</style>src/routes/[[locale=locale]]/+page.ts复制代码复制代码到剪贴板
export const prerender = true;src/routes/[[locale=locale]]/+page.svelte复制代码复制代码到剪贴板
<script lang="ts"> import { useIntlayer } from "svelte-intlayer"; // 使用 home 内容字典 const homeContent = useIntlayer('home');</script><svelte:head> <title>{$homeContent.title.value}</title></svelte:head><section> <h1> {$homeContent.title} </h1></section><style> /* */</style>国际化链接
可选为了 SEO,建议用语言环境前缀你的路由(例如
/en/about、/fr/about)。此组件自动用当前语言环境前缀任何链接。src/lib/components/LocalizedLink.svelte复制代码复制代码到剪贴板
<script lang="ts"> import { getLocalizedUrl } from "intlayer"; import { useLocale } from "svelte-intlayer"; let { href = "" } = $props(); const { locale } = useLocale(); // 使用当前语言环境前缀 URL 的 Helper $: localizedHref = getLocalizedUrl(href, $locale);</script><a href={localizedHref}> <slot /></a>如果你使用 SvelteKit 中的
goto,你可以使用相同的逻辑与getLocalizedUrl来导航到本地化的 URL:typescript复制代码复制代码到剪贴板
import { goto } from "$app/navigation";import { getLocalizedUrl } from "intlayer";import { useLocale } from "svelte-intlayer";const { locale } = useLocale();const localizedPath = getLocalizedUrl("/about", $locale);goto(localizedPath); // 根据语言环境导航到 /en/about 或 /fr/about语言切换器
可选为了允许用户切换语言,更新 URL。
src/lib/components/LanguageSwitcher.svelte复制代码复制代码到剪贴板
<script lang="ts"> import { getLocalizedUrl, getLocaleName } from 'intlayer'; import { useLocale } from "svelte-intlayer"; import { page } from '$app/stores'; import { goto } from '$app/navigation'; const { locale, setLocale, availableLocales } = useLocale({ onLocaleChange: (newLocale) => { const localizedPath = getLocalizedUrl($page.url.pathname, newLocale); goto(localizedPath); }, });</script><ul class="locale-list"> {#each availableLocales as localeEl} <li> <a href={getLocalizedUrl($page.url.pathname, localeEl)} onclick={(e) => { e.preventDefault(); setLocale(localeEl); // 将在 store 中设置语言环境并触发 onLocaleChange }} class:active={$locale === localeEl} > {getLocaleName(localeEl)} </a> </li> {/each}</ul><style> /* */</style>添加后端代理
可选要将后端代理添加到你的 SvelteKit 应用,你可以使用
vite-intlayer插件提供的intlayerProxy函数。此插件将根据 URL、cookies 和浏览器语言首选项自动检测用户的最佳语言环境。自 Intlayer v9 起,
intlayerProxy()直接捆绑到intlayer()插件中,并通过routing.enableProxy选项(默认值为true)默认启用。如下所示单独注册现在是可选的 — 为了向后兼容以及需要控制插件顺序的设置而保留。设置routing.enableProxy: false来选择不使用。查看 v9 发布说明。vite.config.ts复制代码复制代码到剪贴板
import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";import { sveltekit } from "@sveltejs/kit/vite";// https://vitejs.dev/config/export default defineConfig({ plugins: [ intlayer({ proxy: { ignore: (req) => req.url?.startsWith("/api"), }, }), sveltekit(), ],});设置 intlayer 编辑器 / CMS
可选要设置 intlayer 编辑器,你必须遵循 intlayer 编辑器文档。
要设置 intlayer CMS,你必须遵循 intlayer CMS 文档。
为了能够可视化 intlayer 编辑器选择器,你必须在你的 intlayer 内容中使用组件语法。
Component.svelte复制代码复制代码到剪贴板
<script lang="ts"> import { useIntlayer } from "svelte-intlayer"; const content = useIntlayer("component");</script><div> <!-- 将内容呈现为简单内容 --> <h1>{$content.title}</h1> <!-- 将内容呈现为组件(编辑器需要) --> {@const Component = $content.component}<Component /></div>提取你的组件内容
可选如果你有现有的 codebase,转换数千个文件可能很耗时。
为了简化这个过程,Intlayer 提供了一个编译器 / 提取器来转换你的组件并提取内容。
要设置它,你可以在你的
intlayer.config.ts文件中添加一个compiler部分:intlayer.config.ts复制代码复制代码到剪贴板
import { type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { // ... 你的配置的其余部分 compiler: { /** * 指示编译器是否应启用。 */ enabled: true, /** * 定义输出文件路径 */ output: ({ fileName, extension }) => `./${fileName}${extension}`, /** * 指示组件在转换后是否应保存。 * * - 如果为 `true`,编译器将在磁盘中重写组件文件。所以转换将是永久的,编译器将跳过下一个过程的转换。这样,编译器可以转换应用,然后可以将其删除。 * * - 如果为 `false`,编译器将仅在构建输出中注入 `useIntlayer()` 函数调用,并保持基础 codebase 完整。转换将仅在内存中进行。 */ saveComponents: false, /** * 字典 key 前缀 */ dictionaryKeyPrefix: "", }, }; export default config;运行提取器来转换你的组件并提取内容
bash复制代码复制代码到剪贴板
npx intlayer extract
Git 配置
建议忽略 Intlayer 生成的文件。
复制代码到剪贴板
# 忽略 Intlayer 生成的文件.intlayer深入了解
- 可视化编辑器:集成Intlayer 可视化编辑器,以便直接从用户界面编辑翻译内容。
- CMS:使用Intlayer CMS实现内容管理的外部化。