SvelteKit i18n: Hướng dẫn thiết lập quốc tế hóa
Từ con số không đến ứng dụng đa ngôn ngữ: thiết lập svelte-i18n trong ứng dụng SvelteKit bằng định dạng thông điệp ICU, định tuyến theo ngôn ngữ và chuỗi dự phòng thông minh.
Cài đặt svelte-i18n
svelte-i18n là thư viện quốc tế hóa tiêu chuẩn cho Svelte và SvelteKit. Thư viện cung cấp store phản ứng, hỗ trợ ICU MessageFormat và tải lười ngôn ngữ ngay khi cài đặt.
npm install svelte-i18nCấu hình svelte-i18n
Tạo tệp cấu hình i18n để đăng ký các ngôn ngữ bằng hàm import tải lười. svelte-i18n chỉ lấy thông điệp của một ngôn ngữ khi ngôn ngữ đó được kích hoạt.
// src/lib/i18n.ts
import { register, init, getLocaleFromNavigator } from 'svelte-i18n';
// Register locale loaders (lazy-loaded)
register('en', () => import('../locales/en.json'));
register('de', () => import('../locales/de.json'));
register('ja', () => import('../locales/ja.json'));
register('es', () => import('../locales/es.json'));
init({
fallbackLocale: 'en',
initialLocale: getLocaleFromNavigator(), // Auto-detect browser language
});Tích hợp layout SvelteKit
Import cấu hình i18n trong layout gốc và kiểm soát việc kết xuất bằng store $isLoading. Cách này ngăn khóa chưa dịch lóe lên trong khi dữ liệu ngôn ngữ tải bất đồng bộ.
<!-- src/routes/+layout.svelte -->
<script>
// Import i18n config — must run before any component renders
import '../lib/i18n';
import { isLoading } from 'svelte-i18n';
</script>
{#if $isLoading}
<p>Loading translations...</p>
{:else}
<slot />
{/if}Định tuyến theo ngôn ngữ trong SvelteKit
Để có URL thân thiện với SEO như /en/about và /de/about, hãy dùng tham số route [lang]. Đặt ngôn ngữ svelte-i18n trong hàm load của layout dựa trên tham số URL.
// src/routes/[lang]/+layout.ts
import { locale } from 'svelte-i18n';
export function load({ params }) {
// Set the active locale from the URL parameter
locale.set(params.lang);
return {};
}
// src/routes/[lang]/+layout.svelte
<script>
import '../../lib/i18n';
import { isLoading } from 'svelte-i18n';
</script>
{#if $isLoading}
<p>Loading...</p>
{:else}
<slot />
{/if}Định dạng tệp bản dịch
Tạo một tệp JSON cho mỗi ngôn ngữ. svelte-i18n hỗ trợ khóa lồng nhau và cú pháp ICU MessageFormat cho số nhiều, biến và biểu thức select.
// src/locales/en.json
{
"nav": {
"home": "Home",
"about": "About",
"settings": "Settings"
},
"greeting": "Hello, {name}!",
"cart": {
"itemCount": "{count, plural, one {# item} other {# items}}"
}
}
// src/locales/de.json
{
"nav": {
"home": "Startseite",
"about": "Uber uns",
"settings": "Einstellungen"
},
"greeting": "Hallo, {name}!",
"cart": {
"itemCount": "{count, plural, one {# Artikel} other {# Artikel}}"
}
}Dùng bản dịch trong component
Import store $_ (hoặc $format) từ svelte-i18n rồi dùng trong template Svelte. Store có tính phản ứng: khi ngôn ngữ thay đổi, mọi chuỗi dịch tự động cập nhật.
<script>
import { _ } from 'svelte-i18n';
</script>
<h1>{$_('greeting', { values: { name: 'World' } })}</h1>
<nav>
<a href="/">{$_('nav.home')}</a>
<a href="/about">{$_('nav.about')}</a>
</nav><script>
import { _, date, number, time } from 'svelte-i18n';
</script>
<!-- Simple string -->
<p>{$_('greeting', { values: { name: userName } })}</p>
<!-- ICU plurals — handled automatically -->
<p>{$_('cart.itemCount', { values: { count: 3 } })}</p>
<!-- Date formatting -->
<p>{$date(new Date(), { format: 'long' })}</p>
<!-- Number formatting -->
<p>{$number(1999.99, { style: 'currency', currency: 'USD' })}</p>Chuyển đổi ngôn ngữ
Tạo bộ chọn ngôn ngữ liên kết với store $locale. Khi giá trị thay đổi, svelte-i18n tải thông điệp của ngôn ngữ mới và cập nhật mọi chuỗi dịch theo cơ chế phản ứng.
<script>
import { locale, locales } from 'svelte-i18n';
const LANGUAGE_NAMES = {
en: 'English',
de: 'Deutsch',
ja: '日本語',
es: 'Espanol',
};
</script>
<select bind:value={$locale}>
{#each $locales as loc}
<option value={loc}>{LANGUAGE_NAMES[loc] ?? loc}</option>
{/each}
</select>Xử lý số nhiều bằng ICU MessageFormat
svelte-i18n dùng ICU MessageFormat cho số nhiều, tiêu chuẩn quốc tế xử lý mọi nhóm số nhiều CLDR. Tiếng Ả Rập có 6 dạng, tiếng Nga có 4, tiếng Nhật có 1. Hãy khai báo các dạng mà ngôn ngữ đích cần, svelte-i18n sẽ tự động chọn đúng dạng.
// svelte-i18n uses ICU MessageFormat for plurals
// English:
{
"items": "{count, plural, one {# item} other {# items}}"
}
// Arabic (6 forms):
{
"items": "{count, plural, zero {no items} one {item} two {two items} few {# items} many {# items} other {# items}}"
}
// Japanese (1 form):
{
"items": "{count, plural, other {#個のアイテム}}"
}Chuỗi dự phòng ngôn ngữ thông minh với svelte-i18n-locale-chain
svelte-i18n chuyển thẳng sang fallbackLocale khi thiếu khóa, không có bước dự phòng trung gian. Người dùng pt-BR sẽ thấy tiếng Anh thay vì bản dịch pt-PT hoàn toàn phù hợp. svelte-i18n-locale-chain khắc phục bằng chuỗi dự phòng thông minh hợp nhất sâu thông điệp từ các biến thể vùng.
npm install svelte-i18n-locale-chain svelte-i18n// src/lib/i18n.ts
import { initLocaleChain, setLocale } from 'svelte-i18n-locale-chain';
// Replace svelte-i18n's init + register with initLocaleChain
await initLocaleChain({
loadMessages: (locale) =>
import(`../locales/${locale}.json`).then(m => m.default),
defaultLocale: 'en',
initialLocale: 'pt-BR',
});
// Later, to change locale:
await setLocale('fr-CA');
// fr-CA user sees: fr-CA messages -> fr messages -> en messages
// No missing keys — deep-merged automaticallyTự động hóa dịch thuật
Sau khi thiết lập xong i18n, hãy dùng AI để dịch các tệp ngôn ngữ. Trong IDE, bạn có thể yêu cầu trợ lý AI dịch tệp nguồn hoặc dùng i18n Agent CLI trong quy trình CI/CD.
# In your IDE, ask your AI assistant:
> Translate src/locales/en.json to German, Japanese, and Spanish
✓ de.json created (1.2s)
✓ ja.json created (1.5s)
✓ es.json created (1.1s)
# Or use the CLI in CI/CD:
npx i18n-agent translate src/locales/en.json --lang de,ja,esTự động kiểm soát chất lượng bản dịch
Lỗi thường gặp
Rò rỉ ngôn ngữ SSR trong SvelteKit
Dùng register() với svelte-i18n-locale-chain
Lỗi cú pháp ICU không hiện cảnh báo
Nội dung chưa dịch lóe lên
Cấu trúc tệp khuyên dùng
my-sveltekit-app/
├── src/
│ ├── lib/
│ │ └── i18n.ts # i18n configuration
│ ├── locales/
│ │ ├── en.json # Source language
│ │ ├── de.json # German
│ │ ├── ja.json # Japanese
│ │ └── es.json # Spanish
│ └── routes/
│ ├── +layout.svelte # Import i18n, guard isLoading
│ ├── +page.svelte
│ └── [lang]/ # Optional: locale-based routing
│ ├── +layout.ts # Set locale from URL param
│ ├── +layout.svelte
│ └── +page.svelte
├── svelte.config.js
└── package.jsonDùng thử i18n Agent ngay
Thả tệp bản dịch của bạn vào đây
JSON, YAML, PO, XML, CSV, Markdown, Properties
hoặc nhấp để duyệt
Ngôn ngữ đích
Dự phòng ngôn ngữ với svelte-i18n-locale-chain
Khi thiếu khóa bản dịch trong một ngôn ngữ vùng như pt-BR, svelte-i18n chuyển thẳng sang ngôn ngữ mặc định thay vì kiểm tra ngôn ngữ cha pt trước.
npm install svelte-i18n-locale-chainimport { initLocaleChain } from 'svelte-i18n-locale-chain';
initLocaleChain({
fallbacks: {
'pt-BR': ['pt', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
},
defaultLocale: 'en',
});Xem Hướng dẫn dự phòng ngôn ngữ để biết danh sách đầy đủ các framework được hỗ trợ và 75 chuỗi tích hợp sẵn. Learn more →