วิธีแปลไฟล์ i18next JSON ใน React และ Next.js (2026)

คุณเพิ่งสร้างแอป React เสร็จ ซึ่งต้องส่งมอบเป็น 12 ภาษาภายในวันศุกร์หน้า ไฟล์ locale ของคุณอยู่ที่ public/locales/en/common.json มีคีย์ 340 คีย์ต่อ locale และโทเค็นภายในสตริงของคุณมีลักษณะเช่น {{userName}} และ {{count}} กระจัดกระจายอยู่ทั่วออบเจกต์ที่ซ้อนกัน คุณวาง JSON ลงใน ChatGPT แล้วมันก็ส่งกลับมาพร้อมกับ {{ nombreUsuario }}, ช่องว่างพิเศษ และคีย์สำหรับการทำรูปพหูพจน์ครึ่งหนึ่งถูกเปลี่ยนชื่อ แอปของคุณจะหยุดทำงานเมื่อสร้าง
หากคุณเคยพยายามทำให้การแปล i18next JSON เป็นอัตโนมัติ คุณจะเข้าใจถึงความยุ่งยากนี้ดี รูปแบบ JSON มีความยืดหยุ่น ซึ่งเป็นเหตุผลว่าทำไมเครื่องมือแปลส่วนใหญ่ถึงทำให้มันเสียหาย ปัญหาที่แท้จริงไม่ใช่คุณภาพของโมเดลภาษา แต่เป็นเพราะเครื่องมือ AI ระดับผู้บริโภคไม่เข้าใจกฎโครงสร้างของ i18next
คู่มือนี้จะอธิบายว่าอะไรทำให้ i18next JSON แตกต่างจากรูปแบบ locale อื่นๆ ทำไมวิธีการแปลที่ง่ายเกินไปถึงทำให้แอป React และ Next.js เสียหาย และวิธีการทำให้การแปลเป็นอัตโนมัติอย่างปลอดภัยในหลายสิบ locales โดยไม่ต้องตรวจสอบทุกคีย์ด้วยตนเอง
i18next JSON คืออะไร และทำไมการแปลถึงยุ่งยาก
i18next เป็นไลบรารี i18n ที่ใช้กันอย่างแพร่หลายที่สุดในระบบนิเวศของ JavaScript มันขับเคลื่อน React (react-i18next), Next.js (next-i18next, App Router next-intl), Vue และบริการแบ็กเอนด์ของ Node มันจัดเก็บสตริงที่สามารถแปลได้ในไฟล์ JSON แบบแบนหรือแบบซ้อนกัน โดยหนึ่งไฟล์ต่อหนึ่ง locale
ไฟล์ทั่วไปมีลักษณะดังนี้:
{
"welcome": "Welcome, {{userName}}!",
"cart": {
"empty": "Your cart is empty",
"items_one": "{{count}} item in your cart",
"items_other": "{{count}} items in your cart"
},
"errors": {
"network": "Network error. <strong>Please retry</strong>."
}
}
สิ่งนี้ดูเรียบง่าย แต่มีสามสิ่งที่ทำให้การแปลด้วย AI ทั่วไปเป็นอันตราย
โทเค็นการแทรกค่าเป็นโครงสร้าง ไม่ใช่ข้อความ
ลำดับ {{userName}} ไม่ใช่คำ แต่เป็นตัวยึดตำแหน่งที่รันไทม์จะแทนที่ด้วยข้อมูล เพิ่มช่องว่าง ({{ userName }}), เปลี่ยนชื่อ หรือแปลตัวระบุภายใน แล้วรันไทม์จะล้มเหลวอย่างเงียบๆ หรือส่งข้อผิดพลาด นักแปลบางคนแปลง {{count}} เป็น {{conteo}} ในภาษาสเปนอย่างเป็นประโยชน์ ตอนนี้แอปของคุณพยายามที่จะแทรกตัวแปรที่ไม่มีอยู่จริง และแสดงตัวยึดตำแหน่งดิบแก่ผู้ใช้ของคุณ
คีย์รูปพหูพจน์คือคำต่อท้ายมหัศจรรย์
i18next ตรวจจับรูปพหูพจน์ด้วยคำต่อท้าย: _zero, _one, _two, _few, _many, _other สิ่งเหล่านี้ไม่ใช่สตริงที่กำหนดขึ้นเอง — พวกมันต้องตรงกับหมวดหมู่พหูพจน์ของ CLDR สำหรับ locale เป้าหมาย ภาษาอังกฤษใช้แค่ _one และ _other ภาษารัสเซีย, อาหรับ และโปแลนด์ ใช้ได้สูงสุดหกหมวดหมู่ หากนักแปลของคุณละทิ้ง _other หรือเปลี่ยนชื่อ มันจะทำให้ห่วงโซ่การสำรองข้อมูลเสียหาย
คีย์ที่ซ้อนกันต้องคงสภาพเดิม
ไม่เหมือนไฟล์ Gettext .po ซึ่งเป็นคู่คีย์-ค่าแบบแบน ไฟล์ i18next สามารถซ้อนกันได้ตามอำเภอใจ นักแปลที่ขี้เกียจอาจปรับโครงสร้างให้แบนลง, เปลี่ยนชื่อคีย์ให้ตรงกับข้อความที่แปล หรือจัดเรียงออบเจกต์ใหม่ การเรียกใช้ t('cart.items_other') ในโค้ดของคุณจะไม่สามารถแก้ไขได้อีกต่อไป
วิธีแก้ปัญหาที่ไม่ดีที่นักพัฒนาลองใช้เป็นอันดับแรก
ทุกทีมต้องผ่านวงจรความล้มเหลวสามขั้นตอนแบบเดียวกันก่อนที่จะลงทุนในโซลูชันที่แท้จริง
ขั้นตอนที่หนึ่ง: วางลงใน ChatGPT
คุณคัดลอกคีย์ 200 คีย์ลงใน ChatGPT ถามว่า "translate this JSON to Spanish" และวางผลลัพธ์กลับไป มันใช้งานได้สำหรับ 180 คีย์ ยี่สิบคีย์มีช่องว่างถูกเพิ่มเข้าไปใน {{...}} สามคีย์มีคำต่อท้ายรูปพหูพจน์ถูกเขียนใหม่ และแท็ก <strong> หนึ่งอันถูกแปลเป็น <fuerte> การสร้างของคุณจะล้มเหลว หรือไม่ก็ส่งสตริงที่เสียหายอย่างเงียบๆ ไปยังเวอร์ชันใช้งานจริง
ขั้นตอนที่สอง: Google Translate API
คุณเชื่อมต่อ Google Translate REST API วนซ้ำใน JSON ของคุณ และส่งแต่ละค่า ความเร็วดีเยี่ยม แต่คุณภาพไม่ดี API ของ Google ถือว่าแต่ละสตริงแยกจากกัน — ไม่มีบริบทเกี่ยวกับแอปของคุณ, ไม่เข้าใจว่า {{count}} เป็นตัวยึดตำแหน่ง, ไม่รู้ว่าคีย์ cart.empty แตกต่างจาก cart.items_one คุณยังคงต้องมีการตรวจสอบโดยมนุษย์ในทุกคีย์
ขั้นตอนที่สาม: แพลตฟอร์ม TMS เชิงพาณิชย์
คุณสมัครใช้งานระบบจัดการการแปล (translation management system) พวกเขาคิดค่าบริการตามคำ, ต้องมีการผสานรวมกับ GitHub และผูกมัดคุณด้วยการสมัครรายเดือน สำหรับโปรเจกต์เสริมหรือแอปอินดี้, เศรษฐศาสตร์จะพังทลายอย่างรวดเร็ว — และคุณยังคงพบปัญหาการเสียหายของตัวยึดตำแหน่งแบบเดียวกัน หากเอนจินของพวกเขาไม่ได้แยกวิเคราะห์รูปแบบ i18next โดยเฉพาะ
รูปแบบความล้มเหลวแบบเดียวกันนี้ยังปรากฏในเวิร์กโฟลว์ของ Gettext ด้วย คู่มือของเราเรื่อง วิธีแปลไฟล์ .po โดยไม่ทำให้ตัวแปรโค้ดเสียหาย ครอบคลุมปัญหาที่คล้ายกันสำหรับ WordPress และสแต็กอื่นๆ ที่ใช้ Gettext
วิธีที่ปลอดภัย: การแปลที่รับรู้ไวยากรณ์
วิธีเดียวที่เชื่อถือได้ในการแปล i18next JSON ในวงกว้างคือการใช้เครื่องมือที่แยกวิเคราะห์รูปแบบก่อน ล็อกไวยากรณ์ และส่งเฉพาะข้อความที่แปลได้ไปยัง AI เท่านั้น
นี่คือสิ่งที่การประมวลผลที่รับรู้ไวยากรณ์ทำเบื้องหลัง:
- แยกวิเคราะห์ JSON เป็นต้นไม้แบบนามธรรม โดยรักษาวิถีคีย์ (key paths) และการซ้อนกัน
- ระบุโทเค็นการแทรกค่า (
{{name}},{{count, number}},{{date, datetime}}) และแทนที่ด้วย ID ตัวยึดตำแหน่ง - ระบุแท็ก HTML ภายในคอมโพเนนต์ Trans (
<0>,<strong>,<br/>) และล็อกไว้ - ตรวจจับคีย์พหูพจน์ด้วยคำต่อท้าย และแมปกับกฎ CLDR สำหรับ locale เป้าหมาย
- ส่งเฉพาะข้อความที่สะอาดไปยัง LLM พร้อมบริบทเกี่ยวกับวิถีคีย์
- แทรกโทเค็นและแท็กเดิมกลับในตำแหน่งที่แน่นอน
- ตรวจสอบความถูกต้องของเอาต์พุต - หากตัวยึดตำแหน่งใดขาดหายไปหรือมีรูปแบบผิดพลาด จะย้อนกลับไปยังแหล่งที่มา
นี่คือหลักการเดียวกันที่ทำให้การแปล PO บนคลาวด์ปลอดภัย หากคุณอยากรู้เกี่ยวกับสถาปัตยกรรมเบื้องหลัง การเปรียบเทียบคุณภาพการแปล AI ของเราจะอธิบายว่า LLM ที่แตกต่างกันจัดการกับข้อจำกัดเหล่านี้อย่างไร
ขั้นตอน: การแปล i18next JSON ด้วย SimplePoTranslate
SimplePoTranslate รองรับ i18next JSON โดยกำเนิดในแพลน Pro และ Lifetime แพลนฟรีในปัจจุบันครอบคลุมไฟล์ .po และ .pot — อัปเกรดหรือใช้ช่วงทดลองเพื่อเข้าถึง JSON
1. เตรียมไฟล์ต้นฉบับของคุณ
ใช้ไฟล์ภาษาอังกฤษของคุณ (หรือ locale ต้นฉบับ) เป็นไฟล์หลัก ตรวจสอบให้แน่ใจว่าเป็น JSON ที่ถูกต้อง และมีคีย์ทั้งหมดที่แอปของคุณใช้ ข้อผิดพลาดทั่วไปคือการทิ้งคีย์ที่เก่าหรือไม่ใช้งาน ซึ่งจะใช้โควต้าการแปลของคุณไปกับสตริงที่คุณจะไม่มีวันแสดงผล
# From your project root
cp public/locales/en/common.json ~/Desktop/common.json
2. อัปโหลดไปยัง SimplePoTranslate
เข้าสู่ระบบแดชบอร์ดของคุณ คลิก New Translation และอัปโหลด common.json แพลตฟอร์มจะตรวจจับรูปแบบ i18next โดยอัตโนมัติ เลือกภาษาเป้าหมายของคุณจาก 41 locales ที่รองรับ เลือกโทน (เป็นทางการ, ไม่เป็นทางการ, การตลาด) แล้วส่ง
3. ให้เอนจินทำงาน
เบื้องหลัง ไฟล์จะถูกแยกวิเคราะห์ แบ่งเป็นกลุ่มย่อยที่ปลอดภัย และแปลแบบขนาน โทเค็นการแทรกค่าจะถูกล็อก คำต่อท้ายรูปพหูพจน์จะถูกรักษาไว้และแมปกับกฎ CLDR ของ locale เป้าหมาย HTML ภายในคอมโพเนนต์ Trans จะคงสภาพเดิม
4. ดาวน์โหลดไฟล์ ZIP
คุณจะได้ไฟล์ ZIP ที่มี JSON ที่แปลแล้ว พร้อมกับรูปแบบอื่นๆ (.php สำหรับแอป PHP, .po สำหรับความเข้ากันได้ข้ามเครื่องมือ) วาง JSON ลงใน public/locales/es/common.json และปรับใช้ใหม่
unzip common_es.zip
mv common.json public/locales/es/common.json
npm run build
5. ทำซ้ำหรือจัดการเป็นชุด
สำหรับ 12 locales เป้าหมายทั้งหมด ให้ส่ง 12 งาน โควต้าของแพลน Pro ครอบคลุมแอป SaaS ทั่วไปได้หลายสิบแอป สำหรับ monorepos ที่มีไฟล์เนมสเปซหลายไฟล์ ให้อัปโหลดแต่ละไฟล์แยกกัน หรือจัดการเป็นชุดตามลำดับ
การผสานรวมคำแปลกลับเข้าสู่แอปของคุณ
เมื่อคุณมีไฟล์ JSON ที่แปลแล้ว การผสานรวมก็เป็นส่วนที่ง่าย มีข้อควรระวังบางประการ:
- ตรวจสอบหมวดหมู่พหูพจน์ รัน smoke test อย่างรวดเร็วสำหรับแต่ละ locale: แสดงผลคอมโพเนนต์ด้วย
count={0},count={1},count={5}และยืนยันว่าทั้งสามค่าสร้างสตริงที่ถูกต้อง - ตรวจสอบ locales ที่เป็น RTL หากคุณแปลเป็นภาษาอาหรับ, ฮีบรู หรือเปอร์เซีย UI ของคุณต้องใช้ CSS ที่รองรับ RTL คู่มือการแปล WordPress RTL ของเราครอบคลุมรูปแบบ CSS ที่ใช้กับแอป React ได้เช่นกัน
- ตั้งค่าห่วงโซ่สำรอง กำหนดค่า i18next ให้กลับไปใช้ภาษาอังกฤษหากคีย์ขาดหายไป เพื่อไม่ให้สถานะการปรับใช้ระหว่างทางทำให้ผู้ใช้หยุดทำงาน
- ล็อกไฟล์ต้นฉบับของคุณใน CI เพิ่มการตรวจสอบที่ปฏิเสธ PRs ที่
en/common.jsonมีการเปลี่ยนแปลงโดยไม่มีการสร้าง locales อื่นๆ ใหม่ ความคลาดเคลื่อนในการแปลเป็นสาเหตุใหญ่ที่สุดของข้อผิดพลาด i18n ในเวอร์ชันใช้งานจริง
สำหรับทีมที่ส่งมอบงานข้าม React, Next.js และฝั่งเซิร์ฟเวอร์ การสร้างทุกรูปแบบจากแหล่งเดียวถือเป็นชัยชนะที่ยิ่งใหญ่ โพสต์ของเราเรื่อง หนึ่งไฟล์เข้า, ห้าไฟล์ออก อธิบายว่าทำไมเอาต์พุตหลายรูปแบบจึงมีความสำคัญต่อการบำรุงรักษาในระยะยาว
เมื่อ JSON ไม่เพียงพอ: การจัดการกรณีที่ซับซ้อน
มีกรณีขอบบางประการที่ต้องดูแลเป็นพิเศษ
ICU MessageFormat
หากโปรเจกต์ของคุณใช้ไวยากรณ์ ICU ({count, plural, one {1 item} other {# items}}) i18next จะถือว่าเป็นการแทรกค่า แต่โครงสร้างจะซับซ้อนกว่า ตรวจสอบให้แน่ใจว่าเครื่องมือแปลของคุณรู้จักพารามิเตอร์ ICU และไม่แปลชื่อหมวดหมู่เช่น one, other หรือตัวระบุรูปแบบเช่น plural, number, date
คอมโพเนนต์ Trans พร้อมโหนด React
<Trans> แสดงผลคอมโพเนนต์ React ภายในสตริงที่แปล โดยจัดทำดัชนีด้วย (<0>, <1>) นักแปลต้องรักษำลำดับแท็กที่แน่นอน การล็อกไวยากรณ์ของ SimplePoTranslate จัดการสิ่งนี้ได้ แต่หากคุณใช้เครื่องมืออื่น ให้ตรวจสอบก่อนส่งมอบ
ไฟล์เนมสเปซ
แอปขนาดใหญ่จะแยก locales ออกเป็นเนมสเปซ: common.json, dashboard.json, checkout.json แปลแต่ละไฟล์แยกกัน — อย่ารวมเข้าด้วยกัน คุณภาพของบริบทจะสูงขึ้นเมื่อวิถีคีย์ของแต่ละเนมสเปซยังคงอยู่ในขอบเขต
สรุปทั้งหมด
การแปล i18next JSON สำหรับแอป React หรือ Next.js ไม่ใช่เรื่องของการเลือกโมเดล AI ที่ดีที่สุด มันเกี่ยวกับการเคารพกฎโครงสร้างของรูปแบบ: การแทรกค่า (interpolations), คำต่อท้ายรูปพหูพจน์ (plural suffixes), คีย์ที่ซ้อนกัน (nested keys) และแท็ก HTML ต้องคงอยู่ตลอดการเดินทางไปกลับ เครื่องมือ AI สำหรับผู้บริโภคจะถือว่า JSON เป็นข้อความที่ไม่มีโครงสร้าง เครื่องมือที่รับรู้ไวยากรณ์จะแยกวิเคราะห์เป็นข้อมูลที่มีโครงสร้าง และแตะต้องเฉพาะส่วนที่แปลได้เท่านั้น
หากคุณกำลังส่งมอบแอปหลายภาษาและเคยคัดลอกและวาง JSON ลงในอินเทอร์เฟซการแชท คุณก็รู้ถึงค่าใช้จ่ายดีอยู่แล้ว: ชั่วโมงของการตรวจสอบด้วยตนเองต่อ locale, ข้อผิดพลาดในการผลิตแบบสุ่ม และกองซ้อนของรูปแบบพหูพจน์ที่เสีย ไปป์ไลน์ที่รับรู้รูปแบบจะขจัดความล้มเหลวเหล่านั้นออกไปทั้งหมด
พร้อมที่จะแปลไฟล์ i18next JSON ของคุณอย่างปลอดภัยแล้วหรือยัง? ลองใช้ SimplePoTranslate ฟรี — ไม่ต้องใช้บัตรเครดิต อัปโหลดครั้งเดียว ส่งมอบใน 41 ภาษา