Skip to main content

SvelteKit i18n : คู่มือการตั้งค่าการรองรับหลายภาษา

จากศูนย์สู่หลายภาษา ตั้งค่า svelte-i18n ในแอป SvelteKit ด้วยรูปแบบข้อความ ICU เส้นทางตามภาษา และลำดับการใช้ภาษาสำรองอัจฉริยะ

1

ติดตั้ง svelte-i18n

svelte-i18n เป็นไลบรารีมาตรฐานสำหรับทำให้ Svelte และ SvelteKit รองรับหลายภาษา มีสโตร์แบบตอบสนอง รองรับ ICU MessageFormat และโหลดภาษาแบบหน่วงเวลาได้ทันที

svelte-i18n ใช้ ICU MessageFormat สำหรับพหูพจน์และตัวแปร ซึ่งเป็นมาตรฐานเดียวกับ FormatJS/react-intl หากคุณมาจาก React ไวยากรณ์ข้อความจะคุ้นเคย
Terminal
npm install svelte-i18n
2

กำหนดค่า svelte-i18n

สร้างไฟล์กำหนดค่า i18n ที่ลงทะเบียนภาษาด้วยฟังก์ชันนำเข้าแบบโหลดหน่วงเวลา svelte-i18n จะดึงข้อความของภาษาเฉพาะเมื่อเปิดใช้ภาษานั้น

src/lib/i18n.ts
// 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
});
คุณต้องนำเข้าไฟล์กำหนดค่า i18n ใน +layout.svelte ก่อนเรนเดอร์คอมโพเนนต์ใดๆ หากคำแปลแสดงคีย์ดิบอย่าง 'nav.home' แสดงว่านำเข้าการกำหนดค่าไม่เร็วพอ

การเชื่อมต่อเลย์เอาต์ SvelteKit

นำเข้าการกำหนดค่า i18n ในเลย์เอาต์รากและควบคุมการเรนเดอร์ด้วยสโตร์ $isLoading วิธีนี้ป้องกันคีย์ที่ยังไม่แปลกะพริบขณะโหลดข้อมูลภาษาแบบอะซิงโครนัส

src/routes/+layout.svelte
<!-- 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}

การกำหนดเส้นทางตามภาษาใน SvelteKit

สำหรับ URL ที่เป็นมิตรกับ SEO อย่าง /en/about และ /de/about ให้ใช้พารามิเตอร์เส้นทาง [lang] ตั้งค่าภาษา svelte-i18n ในฟังก์ชัน load ของเลย์เอาต์ตามพารามิเตอร์ URL

SvelteKit locale routing
// 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}

รูปแบบไฟล์แปล

สร้างไฟล์ JSON หนึ่งไฟล์ต่อภาษา svelte-i18n รองรับคีย์ซ้อนและไวยากรณ์ ICU MessageFormat สำหรับพหูพจน์ ตัวแปร และนิพจน์ select

Translation files
// 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}}"
  }
}
ตั้งชื่อคีย์ตามสิ่งที่อธิบาย ไม่ใช่ตำแหน่งที่แสดง เช่น 'cart.itemCount' ดีกว่า 'homepageCartLabel' คีย์ควรยังใช้ได้หลังออกแบบ UI ใหม่
3

ใช้คำแปลในคอมโพเนนต์

นำเข้าสโตร์ $_ (หรือ $format) จาก svelte-i18n แล้วใช้ในเทมเพลต Svelte สโตร์ตอบสนองต่อการเปลี่ยนแปลง เมื่อภาษาเปลี่ยน ข้อความที่แปลแล้วทั้งหมดจะอัปเดตโดยอัตโนมัติ

Component.svelte
<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>
Formatting helpers
<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>
$_ เป็นสโตร์ Svelte คุณต้องใช้คำนำหน้า $ ในเทมเพลต การเขียน _('key') โดยไม่มีเครื่องหมายดอลลาร์จะคืนออบเจ็กต์สโตร์ ไม่ใช่ข้อความที่แปลแล้ว

การสลับภาษา

สร้างตัวเลือกภาษาที่ผูกกับสโตร์ $locale เมื่อค่าเปลี่ยน svelte-i18n จะโหลดข้อความของภาษาใหม่และอัปเดตข้อความที่แปลแล้วทั้งหมดแบบตอบสนอง

LanguageSwitcher.svelte
<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>
4

จัดการพหูพจน์ด้วย ICU MessageFormat

svelte-i18n ใช้ ICU MessageFormat สำหรับพหูพจน์ ซึ่งเป็นมาตรฐานสากลที่จัดการหมวดหมู่พหูพจน์ CLDR ทั้งหมด ภาษาอาหรับมี 6 รูป รัสเซียมี 4 รูป และญี่ปุ่นมี 1 รูป กำหนดรูปแบบที่ภาษาเป้าหมายต้องใช้ แล้ว svelte-i18n จะเลือกค่าที่ถูกต้องโดยอัตโนมัติ

ICU plural forms by language
// 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 {#個のアイテム}}"
}
อย่าฮาร์ดโค้ดตรรกะเอกพจน์/พหูพจน์ในคอมโพเนนต์ ภาษาอย่างฝรั่งเศสมอง 0 เป็นเอกพจน์ ส่วนอาหรับ รัสเซีย และโปแลนด์มีรูปพหูพจน์ที่ภาษาอังกฤษไม่มี ให้ไวยากรณ์พหูพจน์ ICU จัดการ

การใช้ภาษาสำรองอัจฉริยะด้วย svelte-i18n-locale-chain

svelte-i18n จะถอยไปใช้ fallbackLocale ทันทีเมื่อไม่มีคีย์ โดยไม่มีค่าสำรองระหว่างทาง ผู้ใช้ pt-BR จึงเห็นภาษาอังกฤษแทนคำแปล pt-PT ที่ใช้ได้ดี svelte-i18n-locale-chain แก้ปัญหานี้ด้วยลำดับการใช้ภาษาสำรองอัจฉริยะที่ผสานข้อความเชิงลึกจากรูปแบบภาษาตามภูมิภาค

Terminal
npm install svelte-i18n-locale-chain svelte-i18n
src/lib/i18n.ts
// 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 automatically
svelte-i18n-locale-chain จัดการการโหลดข้อความทั้งหมดภายใน อย่าใช้ฟังก์ชัน register() ของ svelte-i18n ร่วมกัน เพราะ initLocaleChain จัดการการลงทะเบียน โหลด และผสานเชิงลึกให้แล้ว

ทำให้การแปลเป็นอัตโนมัติ

เมื่อตั้งค่า i18n เสร็จแล้ว ให้แปลไฟล์ภาษาด้วย AI โดยบอกผู้ช่วย AI ใน IDE ให้แปลไฟล์ต้นฉบับ หรือใช้ CLI ของ i18n Agent ในไปป์ไลน์ CI/CD

Terminal
# 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,es
แปลแบบเพิ่มทีละส่วน เมื่อเพิ่มคีย์ใหม่ในไฟล์ต้นฉบับ ให้แปลเฉพาะส่วนต่างแทนการสร้างทุกไฟล์ใหม่ วิธีนี้ช่วยรักษาคำแปลที่มนุษย์ตรวจทานแล้ว

ทำให้คุณภาพการแปลเป็นอัตโนมัติ

ใช้ i18n-validate จับคีย์ที่หายไปและตัวยึดตำแหน่งเสียหายก่อนส่งขึ้นใช้งาน แล้วทดสอบ UI ด้วยคำแปลจำลองผ่าน i18n-pseudo ก่อนคำแปลจริงจะมาถึง

ข้อผิดพลาดที่พบบ่อย

ภาษารั่วไหลระหว่าง SSR ใน SvelteKit

สโตร์ svelte-i18n เป็น singleton ใน SSR ของ SvelteKit คำขอพร้อมกันใช้สโตร์เดียวกัน ภาษาของผู้ใช้คนหนึ่งจึงอาจรั่วไปยังผลตอบกลับของอีกคน วิธีแก้ : เรียก locale.set() ในฮุก handle หรือฟังก์ชัน load ของเลย์เอาต์ เพื่อให้แต่ละคำขอได้รับบริบทภาษาที่ถูกต้อง

ใช้ register() ร่วมกับ svelte-i18n-locale-chain

อย่าใช้ฟังก์ชัน register() ของ svelte-i18n หากใช้ svelte-i18n-locale-chain เพราะ initLocaleChain จัดการการโหลดข้อความทั้งหมดภายใน การผสมทั้งสองทำให้โหลดข้อความซ้ำหรือขัดแย้งกัน

ข้อผิดพลาดไวยากรณ์ ICU ล้มเหลวโดยไม่แจ้งเตือน

วงเล็บปีกกาไม่ตรงกันหรือหมวดหมู่พหูพจน์หายไปในข้อความ ICU MessageFormat ทำให้ล้มเหลวโดยไม่แจ้งเตือน โดยแสดงข้อความดิบแทนผลลัพธ์ที่จัดรูปแบบ ให้ตรวจสอบไวยากรณ์ ICU ในไปป์ไลน์ CI

เนื้อหาที่ยังไม่แปลกะพริบ

หากเรนเดอร์คอมโพเนนต์ก่อนโหลดคำแปลเสร็จ ผู้ใช้จะเห็นคีย์ดิบ ควบคุมเลย์เอาต์ด้วย {#if $isLoading}...{:else}...{/if} เพื่อแสดงสถานะโหลดจนกว่าข้อความจะพร้อม

โครงสร้างไฟล์ที่แนะนำ

Project Structure
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.json

แปลรายการต่อไปนี้ได้ด้วย :

ลองใช้ i18n Agent ตอนนี้

ลากและวางไฟล์แปลของคุณที่นี่

JSON, YAML, PO, XML, CSV, Markdown, Properties

หรือคลิกเพื่อเลือกไฟล์

ภาษาเป้าหมาย

ไม่ต้องลงทะเบียนประเมินราคาได้ทันที

การใช้ภาษาสำรองด้วย svelte-i18n-locale-chain

เมื่อไม่มีคีย์คำแปลในภาษาตามภูมิภาคอย่าง pt-BR svelte-i18n จะข้ามไปใช้ภาษาเริ่มต้นทันทีแทนที่จะตรวจภาษาหลัก pt ก่อน

Terminal
npm install svelte-i18n-locale-chain
Configuration
import { initLocaleChain } from 'svelte-i18n-locale-chain';

initLocaleChain({
  fallbacks: {
    'pt-BR': ['pt', 'en'],
    'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
  },
  defaultLocale: 'en',
});

ดูคู่มือการใช้ภาษาสำรองของเราสำหรับรายการเฟรมเวิร์กที่รองรับทั้งหมดและลำดับสำเร็จรูป 75 รายการ Learn more →

คำถามที่พบบ่อย