All 181 docs markdown files translated into 20 languages (apps/docs/<locale>/**). Companion to the i18n code PR; admin-merged because the file count exceeds GitHub's per-PR CI trigger limit. Validated by pnpm i18n:check (all surfaces, 0 stale/missing) and a clean all-locale docs build.
17 KiB
description, i18n_source_hash, i18n_provenance, i18n_output_hash
| description | i18n_source_hash | i18n_provenance | i18n_output_hash |
|---|---|---|---|
| 21 ภาษาที่รองรับ และวิธีสร้างหรือปรับปรุงคำแปลสำหรับ SnapOtter โดยใช้ระบบ i18n ที่บังคับด้วย TypeScript | 55837d9fdaef | human | 2c7c9a24cb4d |
คู่มือการแปล
SnapOtter มาพร้อมกับ 21 ภาษาตั้งแต่ต้น ระบบ i18n ใช้รันไทม์แบบกำหนดเองที่มีขนาดเบา พร้อมการบังคับความสมบูรณ์ของ locale ด้วย TypeScript และการแยกโค้ดแบบไดนามิก
ภาษาที่รองรับ
| Code | Language | Native Name | Direction |
|---|---|---|---|
en |
English | English | LTR |
zh-CN |
Chinese (Simplified) | 简体中文 | LTR |
zh-TW |
Chinese (Traditional) | 繁體中文 | LTR |
ja |
Japanese | 日本語 | LTR |
ko |
Korean | 한국어 | LTR |
es |
Spanish | Español | LTR |
fr |
French | Français | LTR |
it |
Italian | Italiano | LTR |
pt-BR |
Portuguese (Brazil) | Português (Brasil) | LTR |
de |
German | Deutsch | LTR |
nl |
Dutch | Nederlands | LTR |
sv |
Swedish | Svenska | LTR |
ru |
Russian | Русский | LTR |
pl |
Polish | Polski | LTR |
uk |
Ukrainian | Українська | LTR |
ar |
Arabic | العربية | RTL |
tr |
Turkish | Türkçe | LTR |
hi |
Hindi | हिन्दी | LTR |
vi |
Vietnamese | Tiếng Việt | LTR |
id |
Indonesian | Bahasa Indonesia | LTR |
th |
Thai | ไทย | LTR |
การตรวจจับภาษาทำงานอย่างไร
SnapOtter ใช้ลำดับการแก้ไขแบบสามชั้น:
- การตั้งค่าของผู้ใช้ - จัดเก็บใน
localStorage("snapotter-locale")และซิงค์ไปยังการตั้งค่าผู้ใช้เมื่อเข้าสู่ระบบแล้ว - การตรวจจับอัตโนมัติของเบราว์เซอร์ - ไล่ไปตามอาร์เรย์
navigator.languagesด้วยการจับคู่คำนำหน้าแบบ BCP 47 - ค่าเริ่มต้นของอินสแตนซ์ - ตัวแปรสภาพแวดล้อม
DEFAULT_LOCALEของผู้ดูแลระบบ (ดึงมาจากGET /api/v1/config/locale) - การถอยกลับเป็นภาษาอังกฤษ - พร้อมใช้งานเสมอ
ผู้ใช้สามารถเปลี่ยนภาษาได้จาก:
- ตัวเลือกลูกโลกที่ส่วนท้าย (เดสก์ท็อป มองเห็นได้เสมอ)
- ตัวเลือกภาษาที่ หน้าเข้าสู่ระบบ (ก่อนการยืนยันตัวตน)
- ส่วน Settings > General (การตั้งค่าเฉพาะผู้ใช้)
- เมนูดรอปดาวน์ภาษาใน แถบข้างบนมือถือ
- ส่วน Settings > System ตั้งค่าเริ่มต้นทั่วทั้งอินสแตนซ์ (เฉพาะผู้ดูแลระบบ)
การแปลทำงานอย่างไร
สตริง UI ทั้งหมดอยู่ใน packages/shared/src/i18n/ ไฟล์อ้างอิงคือ en.ts ซึ่งส่งออกอ็อบเจกต์ที่มีการกำหนดชนิดข้อมูล พร้อมทุกสตริงที่แอปใช้ (~1500 คีย์) ภาษาอื่นๆ เป็นไฟล์แยกต่างหาก (เช่น de.ts, fr.ts) ที่ส่งออกในรูปแบบเดียวกัน
ชนิด TranslationKeys ใช้ DeepStringRecord เพื่อยอมรับค่าสตริงใดๆ ในขณะที่บังคับโครงสร้างคีย์ TypeScript จะตรวจจับคีย์ที่ขาดหายไปในไฟล์แปลใดๆ ณ เวลาคอมไพล์
จะโหลดเฉพาะ locale ที่ใช้งานอยู่เท่านั้น ณ รันไทม์ผ่าน import() แบบไดนามิก เพื่อให้บันเดิลหลักมีขนาดเล็ก
การใช้คำแปลในคอมโพเนนต์
import { useTranslation } from "@/contexts/i18n-context";
import { format, plural } from "@/lib/format";
function MyComponent() {
const { t, locale, setLocale } = useTranslation();
return (
<div>
<h1>{t.common.settings}</h1>
<p>{format(t.settings.people.deleteConfirm, { username: "admin" })}</p>
<p>{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}</p>
</div>
);
}
การมีส่วนร่วมในการแปล
เรายินดีรับ PR การแปลโดยตรง คุณสามารถปรับปรุง locale ที่มีอยู่หรือเพิ่ม locale ใหม่ได้
หากต้องการรายงานคำแปลที่ผิดโดยไม่ส่งโค้ด ให้เปิด GitHub Issue พร้อมระบุภาษา สตริงที่ไม่ถูกต้อง และการแก้ไขที่แนะนำ
::: tip PR การแปลไม่จำเป็นต้องได้รับการอนุมัติล่วงหน้า ให้ fork repo ทำการเปลี่ยนแปลงของคุณ แล้วเปิด PR ดู Contributing Guide สำหรับกระบวนการ PR ทั้งหมดและข้อกำหนด CLA :::
วิธีสร้างหรืออัปเดตคำแปล
1. Fork และ clone
git clone https://github.com/<your-username>/snapotter.git
cd snapotter
pnpm install
2. คัดลอกไฟล์อ้างอิง (สำหรับภาษาใหม่เท่านั้น)
ข้ามขั้นตอนนี้หากคุณกำลังปรับปรุงคำแปลที่มีอยู่
cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts
3. แปลสตริง
เปิดไฟล์ใหม่ของคุณและแปลค่าสตริงทุกค่า คงโครงสร้างอ็อบเจกต์และคีย์ให้เหมือนกันทุกประการ
import type { TranslationKeys } from "./en.js";
export const xx: TranslationKeys = {
common: {
upload: "Your translation here",
// ... translate all entries
},
// ... translate all sections
} as const;
กฎ:
- อย่าแปลคีย์ของอ็อบเจกต์ แปลเฉพาะค่าสตริงเท่านั้น
- คง
as constไว้ที่ท้าย - นำเข้า
TranslationKeysจาก./en.jsและกำหนดชนิดข้อมูลให้กับ export ของคุณ - คงตัวแทน
{variable}ไว้ตามเดิมทุกประการ - อาร์เรย์ (
rotatingPhrases,progressMessages) ต้องมีจำนวนรายการเท่ากัน - อย่าแปล: SnapOtter, JPEG, PNG, WebP, EXIF, API และคำศัพท์ทางเทคนิคอื่นๆ
4. ลงทะเบียน locale (สำหรับภาษาใหม่เท่านั้น)
เพิ่ม locale ของคุณลงใน SUPPORTED_LOCALES ใน packages/shared/src/i18n/index.ts:
{ code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" },
5. ตรวจสอบ
pnpm typecheck # catches missing or mistyped keys
pnpm lint # formatting check
pnpm dev # manually verify strings appear correctly
6. ส่ง
เปิด PR ต่อ main ด้วยชื่อเรื่องอย่างเช่น feat(i18n): add Swedish translation หรือ fix(i18n): correct German typos บอต CLA จะขอให้คุณลงนามในการมีส่วนร่วมครั้งแรกของคุณ
การเพิ่มคีย์คำแปลใหม่
เมื่อเพิ่มฟีเจอร์ใหม่ที่ต้องการสตริง UI ใหม่:
- เพิ่มคีย์ใหม่ลงใน
en.tsก่อน (ไฟล์อ้างอิง) - รัน
pnpm typecheck- ไฟล์ locale ทุกไฟล์จะล้มเหลวหากขาดคีย์ใหม่ - เพิ่มคีย์ใหม่ลงในไฟล์ locale ทั้งหมด (ใช้ภาษาอังกฤษเป็นค่าถอยกลับชั่วคราว)
การกำหนดค่า
ตั้งค่าภาษาเริ่มต้นของอินสแตนซ์ผ่านตัวแปรสภาพแวดล้อม:
DEFAULT_LOCALE: "de" # German as the default for all new users
การอ้างอิงไฟล์
| File | Purpose |
|---|---|
packages/shared/src/i18n/en.ts |
สตริงภาษาอังกฤษ (locale อ้างอิง, ~1500 คีย์) |
packages/shared/src/i18n/index.ts |
SUPPORTED_LOCALES, loadTranslations(), การส่งออกชนิดข้อมูล |
packages/shared/src/i18n/<locale>.ts |
ไฟล์แปลแยกตามภาษา |
apps/web/src/contexts/i18n-context.tsx |
I18nProvider, ฮุก useTranslation() |
apps/web/src/lib/format.ts |
ตัวช่วย format(), plural(), formatFileSize() |
apps/api/src/routes/config.ts |
จุดปลายทางสาธารณะ GET /api/v1/config/locale |
การแปลเว็บไซต์ เอกสาร และการอ้างอิง API
การรองรับ 21 ภาษาข้างต้นครอบคลุม แอป เว็บไซต์สาธารณะ
(snapotter.com) เว็บไซต์เอกสารนี้ และการอ้างอิง REST API ก็ได้รับการ
แปลเป็นทั้ง 21 ภาษาเช่นกัน โดยไปป์ไลน์ที่กำกับด้วยแฮชแยกต่างหากซึ่งนำ
ชื่อและคำอธิบายเครื่องมือชุดเดียวกันจาก packages/shared/src/i18n มาใช้ซ้ำ ดังนั้น
คำศัพท์จึงสอดคล้องกันทุกที่
แปลด้วยเครื่องเป็นค่าเริ่มต้น
ทุกหน้าที่ไม่ใช่ภาษาอังกฤษบนเว็บไซต์และเอกสารจะได้รับการ แปลด้วยเครื่อง ใน รอบแรก (โดยเซสชัน Claude Code ไม่ใช่บริการภายนอก) และมี แบนเนอร์เล็กๆ ที่ปิดได้แจ้งเรื่องนี้ พร้อมลิงก์กลับมาที่นี่ นั่นเป็นความตั้งใจ: มันจัดส่งทั้ง 21 ภาษาอย่างรวดเร็วและตรงไปตรงมา จากนั้นเชิญชวนชุมชนให้ ปรับปรุงหน้าที่สำคัญที่สุด การแปลด้วยเครื่องสื่อความหมายได้ครบถ้วน การตรวจทานโดยมนุษย์ทำให้อ่านได้เป็นธรรมชาติ
ไปป์ไลน์ตัดสินใจว่าจะแปลอะไรอย่างไร
แต่ละหน่วยของต้นฉบับภาษาอังกฤษที่แปลได้จะถูกแฮช และแฮชจะถูกจัดเก็บ ไว้ข้างคำแปลของมัน ในการรันแต่ละครั้ง ไปป์ไลน์จะ:
- แปลหน่วยใดๆ ที่ยังไม่มีคำแปล
- ข้ามหน่วยใดๆ ที่แฮชที่จัดเก็บไว้ยังตรงกับต้นฉบับภาษาอังกฤษ
- แปลใหม่สำหรับหน่วยที่เป็น machine เมื่อต้นฉบับภาษาอังกฤษเปลี่ยนแปลง
- และตั้งค่าสถานะหน่วยที่ผ่านการปรับปรุงโดย human เป็น
stale(ต้องตรวจทาน) เมื่อต้นฉบับ ภาษาอังกฤษเปลี่ยนแปลง แทนที่จะเขียนทับงานของคุณ
การปรับปรุงคำแปลเว็บด้วย PR
คุณปรับปรุงคำแปลของเว็บไซต์ เอกสาร หรือการอ้างอิง API ด้วยวิธีเดียวกับที่คุณ ปรับปรุง locale ของแอป: โดยแก้ไขไฟล์ที่ถูกสร้างขึ้นและเปิด PR
- ค้นหาคำแปลที่ถูกสร้างขึ้นสำหรับภาษาของคุณ:
- สตริง UI ของเว็บไซต์:
apps/landing/src/i18n/<locale>.json - หน้าเอกสาร:
apps/docs/<locale>/**.md - การอ้างอิง API:
apps/api/src/openapi.<locale>.yaml
- สตริง UI ของเว็บไซต์:
- แก้ไขข้อความ คงโค้ด ลิงก์
{placeholders}และเครื่องหมาย⸤I18N…⸥ใดๆ ไว้ตามเดิมทุกประการ ตัวตรวจสอบของไปป์ไลน์จะปฏิเสธคำแปลที่ทำ เครื่องหมายเหล่านั้นหายไปหรือสลับลำดับ - เปิด PR การแก้ไขหน่วยจะพลิกที่มาของมันจาก
machineเป็นhumanดังนั้น ไปป์ไลน์จะ ไม่มีวันเขียนทับมัน ในการรันครั้งต่อไป หากต้นฉบับภาษาอังกฤษ เปลี่ยนแปลงในภายหลัง หน่วยของคุณจะถูกตั้งค่าสถานะเป็นstaleเพื่อตรวจทานแทนที่จะถูก แทนที่อย่างเงียบๆ
หากต้องการรายงานคำแปลที่ผิดโดยไม่ส่งโค้ด ให้เปิด GitHub Issue พร้อมระบุ URL ของหน้า ภาษา ข้อความที่ไม่ถูกต้อง และการแก้ไขที่คุณแนะนำ
::: tip
ผู้ดูแลจะรันไปป์ไลน์การแปล คุณไม่จำเป็นต้องมี API key เพื่อ
มีส่วนร่วม เพียงแก้ไขไฟล์ที่ถูกสร้างขึ้นและเปิด PR ดู
scripts/i18n/README.md
สำหรับวิธีการทำงานของไปป์ไลน์
:::