22 ส.ค. 2568·อ่าน 3 นาที

เวิร์กโฟลว์ Vue 3 i18n สำหรับ 500+ คีย์ โดยไม่มีปัญหาในโปรดักชัน

เวิร์กโฟลว์ Vue 3 i18n สำหรับแอปขนาดใหญ่: การตั้งชื่อคีย์ กฎพหูพจน์ การตรวจสอบ QA และขั้นตอนปล่อย เพื่อลดคำแปลหายในโปรดักชัน

เวิร์กโฟลว์ Vue 3 i18n สำหรับ 500+ คีย์ โดยไม่มีปัญหาในโปรดักชัน

ปัญหาที่เกิดเมื่อมีคีย์ i18n เกิน 500\n\nเมื่อแอปมีสตริงเป็นร้อย ๆ ข้อที่ทำให้พังไม่ใช่ตัวไลบรารี Vue I18n แต่เป็นความไม่สม่ำเสมอ ผู้คนเพิ่มคีย์ในสไตล์ต่างกัน ทำซ้ำไอเดียเดียวกันในชื่อต่าง ๆ และไม่มีใครแน่ใจว่าข้อความไหนลบได้\n\nคำแปลที่หายก็ไม่ใช่เรื่องยุ่งยากชั่วคราวอีกต่อไป มันโผล่ในเส้นทางผู้ใช้ปกติ โดยเฉพาะจอที่ใช้น้อย เช่น การตั้งค่า สถานะข้อผิดพลาด หน้าว่าง และการแจ้งเตือน\n\nเมื่อคำแปลหาย ผู้ใช้จะเจอความล้มเหลวสามแบบหลัก ๆ: UI ว่าง (ปุ่มไม่มีป้ายชื่อ), คีย์ดิบ ๆ ปรากฏ (เช่น checkout.pay_now), หรือ fallback แปลก ๆ ที่บางส่วนของหน้าเปลี่ยนภาษา สิ่งเหล่านี้ไม่ใช่บั๊กเล็กน้อย — ทำให้แอปดูพัง\n\nดังนั้น workflow ด้าน i18n ใน Vue 3 จึงสำคัญกว่าไลบรารีที่ใช้ ไลบรารีจะทำตามที่คุณสั่ง แต่ในสเกลที่ใหญ่ ทีมมักไม่เห็นพ้องว่าคำว่า “เสร็จ” หมายถึงอะไร\n\nตัวอย่างทั่วไป: นักพัฒนาปล่อยฟลว์ "Invite teammate" ใหม่พร้อมสตริง 40 ข้อ ไฟล์ภาษาอังกฤษถูกอัปเดต แต่ไฟล์ภาษาฝรั่งเศสไม่ถูกอัปเดต ในสเตจทุกอย่างดูปกติเพราะผู้ทดสอบใช้ภาษาอังกฤษ แต่ในโปรดักชัน ผู้ใช้ฝรั่งเศสจะเห็น UI ผสมกันระหว่างแปลและไม่แปล และฝ่ายซัพพอร์ตได้ภาพหน้าจอของคีย์ดิบ\n\nวิธีแก้คือการนิยามว่า “เสร็จ” สำหรับ UI ที่แปลแล้วคืออะไร ไม่สามารถเป็นแค่ "เพิ่มสตริงแล้ว" เท่านั้น คำจำกัดความที่ใช้ได้จริงมักรวม: คีย์เป็นไปตามกฎการตั้งชื่อ, locales สร้างได้โดยไม่มีคำเตือน missing-key, พหูพจน์และตัวแปรแสดงผลถูกต้องด้วยข้อมูลจริง, ตรวจเช็คอย่างน้อยหนึ่ง locale ที่ไม่ใช่ค่าเริ่มต้น และการเปลี่ยนแปลงสำเนาต้องมีการติดตามเพื่อไม่ให้คีย์เก่าค้างอยู่\n\nเมื่อมีคีย์ 500+ ให้มองการทำ localization เหมือนกระบวนการปล่อย ไม่ใช่งานแก้ไขไฟล์นาทีสุดท้าย\n\n## กำหนดกฎไม่กี่ข้อก่อนเพิ่มสตริงมากขึ้น\n\nหลังจากมีสตริงเป็นร้อย งานแปลไม่ใช่ปัญหาใหญ่ที่สุด แต่ความไม่สม่ำเสมอคือปัญหา ชุดกฎเล็ก ๆ จะทำให้ workflow Vue 3 i18n ของคุณคาดเดาได้ แม้หลายคนจะแตะข้อความทุกสัปดาห์\n\nเริ่มจากตัดสินใจว่า “แนวคิด” หนึ่งคืออะไรและเก็บแหล่งข้อมูลเดียวสำหรับมัน ถ้าไอเดีย UI เดียวกันปรากฏในห้าที่ (เช่น “Save changes”) คุณต้องการคีย์เดียว ไม่ใช่ห้าชื่ออย่าง save, saveChanges, save_update, และ saveBtn คีย์ซ้ำ ๆ จะเปลี่ยนความหมายเมื่อเวลาผ่านไป และผู้ใช้จะรู้สึกถึงความไม่สอดคล้องกัน\n\nต่อมา ตัดสินใจว่าการจัดรูปแบบอยู่ที่ไหน ทีมมักแบ่งหน้าที่นี้โดยไม่ได้ตั้งใจ: บางข้อความมีเครื่องหมายวรรคตอนและตัวพิมพ์ บางข้อความให้โค้ดจัดให้ เลือกแนวทางหนึ่งแล้วยึดตามมัน\n\nค่าเริ่มต้นที่ใช้ได้จริง:\n\n- ใส่ไวยากรณ์ เครื่องหมายวรรคตอน และการจัดรูปแบบที่ผู้ใช้เห็น (เช่น “(optional)”) ไว้ในข้อความ\n- เก็บการจัดรูปแบบข้อมูลที่เป็น pure data ในโค้ด (วันที่ สกุลเงิน หน่วย) แล้วส่งผลลัพธ์เข้า i18n\n- ใช้ placeholder สำหรับชื่อและจำนวน ไม่ใช้การต่อสตริง\n- ถือว่า HTML ในข้อความเป็นกรณีพิเศษและมีกฎชัดเจน (อนุญาตหรือไม่อนุญาต)\n\nจากนั้นกำหนดความเป็นเจ้าของ ตัดสินใจว่าใครเพิ่มคีย์ใหม่ ใครรีวิวข้อความภาษาเบส และใครอนุมัติ locales อื่น ๆ ถ้าไม่มีสิ่งนี้ สตริงจะถูกเพิ่มแบบรีบ ๆ แล้วไม่เคยได้รับการตรวจสอบ\n\nสุดท้าย เลือกและบันทึกกลยุทธ์ fallback หากคีย์หาย ผู้ใช้ควรเห็นอะไร: ชื่อคีย์ ข้อความของ default-locale หรือข้อความทั่วไปปลอดภัย? หลายทีมในโปรดักชันชอบ fallback ไปที่ default locale แล้วทำ logging ด้วย เพื่อผู้ใช้ไม่ติดขัดและทีมยังได้สัญญาณว่ามีปัญหา\n\nถ้าคุณสร้างแอป Vue 3 ด้วยตัวสร้างอย่าง AppMaster (Vue3 web UI พร้อม backend จริง) กฎเหล่านี้ก็ยังใช้ได้ ให้ปฏิบัติต่อคำแปลเหมือนเนื้อหาผลิตภัณฑ์ ไม่ใช่ "แค่ข้อความของ dev" และคุณจะหลีกเลี่ยงความประหลาดใจตอนปลายได้มาก\n\n## ข้อกำหนดการตั้งชื่อคีย์ที่อ่านง่าย\n\nเมื่อมีสตริงเป็นร้อย ความสม่ำเสมอเป็นตัวคูณที่ใหญ่ที่สุด เลือกสไตล์คีย์หนึ่งแบบ (ทีมส่วนใหญ่ใช้ dot paths เช่น billing.invoice.title) แล้วทำเป็นกฎ การผสมจุด ทับ สไตล์ snake_case และการใช้ตัวพิมพ์แบบสุ่ม ทำให้การค้นหาและการรีวิวช้าลง\n\nใช้คีย์ที่มั่นคงต่อการเปลี่ยนแปลงข้อความ คีย์อย่าง "Please enter your email" จะพังทันทีเมื่อการตลาดแก้ประโยค เลือกชื่อที่บอกเจตนา เช่น auth.email.required หรือ auth.email.invalid\n\nจัดกลุ่มคีย์ตามพื้นที่ผลิตภัณฑ์หรือพื้นผิว UI ก่อน แล้วค่อยแบ่งตามวัตถุประสงค์ คิดตามถังเดียวกับที่แอปของคุณมี: auth, billing, settings, support, dashboard วิธีนี้ช่วยให้ไฟล์ locale อ่านง่ายขึ้นและลดการทำซ้ำเมื่อสองหน้าจออยากได้ไอเดียเดียวกัน\n\nภายในแต่ละพื้นที่ เก็บรูปแบบเล็ก ๆ สำหรับชิ้น UI ทั่วไป:\n\n- ปุ่ม: *.actions.save, *.actions.cancel\n- ป้าย: *.fields.email.label, *.fields.password.label\n- คำแนะนำ/ช่วยเหลือ: *.fields.email.hint\n- ข้อผิดพลาด/การตรวจสอบ: *.errors.required, *.errors.invalidFormat\n- การแจ้งเตือน/toasts: *.notices.saved, *.notices.failed\n\nข้อความไดนามิกควรบอกว่าสิ่งไหนเปลี่ยน ไม่ใช่วิธีการตั้งชื่อ ใช้ชื่อโดยเจตนาและพารามิเตอร์สำหรับส่วนที่เปลี่ยน ตัวอย่างเช่น billing.invoice.dueInDays พร้อม {days} ชัดกว่า billing.invoice.dueIn3Days\n\nตัวอย่าง (เหมาะกับ workflow Vue 3 i18n): orders.summary.itemsCount กับ {count} สำหรับจำนวน และ orders.summary.total กับ {amount} สำหรับจำนวนเงิน เมื่ออ่านคีย์ในโค้ด คนควรรู้ว่ามันอยู่ที่ไหนและทำไมถึงมี แม้ข้อความจริงจะเปลี่ยนภายหลัง\n\n## กฎพหูพจน์และการจัดรูปแบบข้อความโดยไม่ประหลาดใจ\n\nข้อความพหูพจน์มักพังโดยเงียบเมื่อคุณถือว่าทุกภาษาคล้ายอังกฤษ ตัดสินใจแต่เนิ่น ๆ ว่าจะใช้ ICU message syntax เมื่อไหร่ และเมื่อไหร่พอแค่ placeholder ธรรมดา\n\nใช้การแทนที่ง่าย ๆ สำหรับป้ายและข้อความสั้นที่ไม่เปลี่ยนตามจำนวน (เช่น "Welcome, {name}") เปลี่ยนไปใช้ ICU สำหรับข้อความที่ขึ้นกับจำนวน เพราะมันรวบรวมทุกรูปแบบไว้ที่เดียวและชัดเจน\n\n```json

{ "notifications.count": "{count, plural, =0 {No notifications} one {# notification} other {# notifications}}" } \n\nเขียนข้อความจำนวนให้แปลง่าย เลือกประโยคเต็มและวาง placeholder ตัวเลข (`#`) ใกล้คำนาม หลีกเลี่ยงการใช้งานช็อตคัตอย่างการใช้คีย์เดียวกันสำหรับ "1 item" และ "2 items" ในโค้ด นักแปลต้องเห็นข้อความทั้งประโยค ไม่ใช่เดาว่าจะประกอบกันอย่างไร\n\nวางแผนสำหรับ `=0`, `one`, และ `other` อย่างน้อย และบันทึกว่าคุณคาดหวังอะไรสำหรับ `0` บางผลิตภัณฑ์อยากได้ “0 items” บางที่อยากได้ “No items” เลือกสไตล์เดียวแล้วยึดตามมันเพื่อให้ UI ดูสม่ำเสมอ\n\nระวังภาษาที่มีหมวดพหูพจน์มากกว่าที่คุณคิด ภาษาหลายภาษามิได้ตามกฎ "one vs many" หากคุณเพิ่ม locale ใหม่ทีหลัง ข้อความที่มีแค่ `one` และ `other` อาจผิดไวยากรณ์แม้จะแสดงผลได้\n\nก่อนปล่อย ทดสอบพหูพจน์ด้วยค่าจริงใน UI ไม่ใช่แค่มอง JSON การเช็กเร็ว ๆ ที่จับปัญหาได้คือ 0, 1, 2, 5 และ 21\n\nถ้าคุณสร้างแอป Vue3 web (เช่น ภายใน AppMaster) ให้ทดสอบบนหน้าจอที่ข้อความปรากฏ ข้อจำกัดพื้นที่ การตัดคำ และสำนวนที่ไม่เหมาะสมจะปรากฏที่นั่นก่อน\n\n## จัดระเบียบไฟล์ locale ให้เติบโตได้\n\nหลังจากมีสตริงเป็นร้อย ไฟล์ `en.json` ใหญ่ ๆ จะเป็นคอขวด ผู้คนแตะไฟล์เดียวกัน ความขัดแย้งในการ merge เพิ่มขึ้น และคุณอาจหลงว่าข้อความอยู่ที่ไหน โครงสร้างที่ดีช่วยให้ workflow Vue 3 i18n ของคุณนิ่งแม้ผลิตภัณฑ์เปลี่ยนบ่อย\n\n### โครงสร้างที่แนะนำ\n\nสำหรับ 2-5 locale การแยกตามฟีเจอร์มักพอแล้ว เก็บเลย์เอาต์ไฟล์ให้เหมือนกันในทุก locale เพื่อให้การเพิ่มคีย์เป็นการแก้ไขที่คาดเดาได้\n\n- `locales/en/common.json`, `locales/en/auth.json`, `locales/en/billing.json`\n- `locales/es/common.json`, `locales/es/auth.json`, `locales/es/billing.json`\n- `locales/index.ts` (โหลดและรวมข้อความ)\n\nสำหรับ 20+ locale ขยายแนวคิดเดียวกันแต่ทำให้การเบี้ยวยากขึ้น ถือว่า English เป็นแหล่งข้อมูลหลักและบังคับให้ทุก locale สะท้อนโฟลเดอร์และชื่อไฟล์เดียวกัน ถ้าโดเมนใหม่ปรากฏ (เช่น `notifications`) มันควรมีในทุก locale แม้ข้อความจะเป็นชั่วคราว\n\nการแยกตามโดเมนลดการชนกันของ merge เพราะคนสองคนสามารถเพิ่มสตริงในไฟล์ต่างกันโดยไม่ชนกัน โดเมนควรตรงกับโครงสร้างแอป: `common`, `navigation`, `errors`, `settings`, `reports` และโฟลเดอร์ฟีเจอร์สำหรับพื้นที่ใหญ่ ๆ\n\n### รักษาความสม่ำเสมอของคีย์\n\nภายในแต่ละไฟล์ รักษารูปร่างคีย์ให้เหมือนกันในทุก locale: การซ้อนกันเหมือนกัน ชื่อคีย์เหมือนกัน ข้อความต่างกัน หลีกเลี่ยงคีย์สร้างสรรค์ในแต่ละภาษา แม้บางวลีจะแปลยาก ถ้า English มี `billing.invoice.status.paid` ทุก locale ต้องมีคีย์นั้นเป๊ะ\n\nรวมศูนย์เฉพาะสิ่งที่ซ้ำจริง ๆ ทั่วทุกที่: ป้ายปุ่มทั่วไป ข้อผิดพลาดการตรวจสอบทั่วไป และ navigation ทั่วไป เก็บข้อความเฉพาะฟีเจอร์ใกล้กับโดเมนฟีเจอร์ แม้จะรู้สึกว่ามันใช้ซ้ำได้ “Save” อยู่ใน `common` แต่ “Save payment method” อยู่ใน `billing`\n\n### เนื้อหายาว\n\nข้อความช่วยเหลือยาว ๆ ขั้นตอน onboarding และเทมเพลตอีเมลจะยุ่งยากเร็ว มีข้อแนะนำ:\n\n- ใส่สตริงยาวในโดเมนของตัวเอง (เช่น `help` หรือ `onboarding`) และหลีกเลี่ยงการซ้อนลึกมาก\n- ชอบย่อหน้าสั้น ๆ แยกกัน แทนสตริงยาวพารากราฟเดียว เพื่อให้นักแปลทำงานได้ปลอดภัย\n- ถ้าการตลาดหรือซัพพอร์ตแก้ข้อความบ่อย ให้เก็บข้อความเหล่านั้นในไฟล์เฉพาะเพื่อลด churn ที่อื่น\n- สำหรับอีเมล เก็บ subject และ body แยกกัน และรักษา placeholder ให้สอดคล้อง (ชื่อ วันที่ จำนวนเงิน)\n\nการตั้งค่านี้ช่วยให้รีวิวการเปลี่ยนแปลง ทำการแปลอย่างต่อเนื่อง และหลีกเลี่ยงช่องว่างที่ไม่คาดคิดก่อนปล่อย\n\n## ขั้นตอนทีละขั้นตอนสำหรับการเพิ่มและปล่อยสตริง\n\nworkflow Vue 3 i18n ที่มั่นคงไม่ใช่เรื่องเครื่องมือ แต่เป็นการทำขั้นตอนเล็ก ๆ เดิม ๆ ทุกครั้ง ข้อความ UI ใหม่ไม่ควรถึงโปรดักชันโดยไม่มีคีย์ ข้อความเริ่มต้น และสถานะการแปลที่ชัดเจน\n\nเริ่มจากเพิ่มคีย์ในภาษาเบสของคุณ (มักเป็น `en`) เขียนข้อความเริ่มต้นให้เป็นสำเนาจริง ๆ ไม่ใช่ placeholder สิ่งนี้ให้ผลิตภัณฑ์และ QA มีอะไรอ่านรีวิว และป้องกัน "สตริงปริศนา" ในภายหลัง\n\nเมื่อใช้คีย์ในคอมโพเนนต์ ให้ใส่ params และตรรกะพหูพจน์ตั้งแต่วันแรกเพื่อให้นักแปลเห็นรูปแบบเต็มของข้อความ\n\njs // simple param $t('billing.invoiceDue', { date: formattedDate })

// plural $t('files.selected', count, { count }) \n\nถ้าการแปลยังไม่พร้อม อย่าปล่อยคีย์ให้หายไป ให้เพิ่มคำแปล placeholder ใน locales อื่นหรือทำเครื่องหมายว่า pending แบบสม่ำเสมอ (เช่น prefix ด้วย `TODO:`) ส่วนสำคัญคือแอปจะแสดงอย่างคาดเดาได้และคนรีวิวมองเห็นข้อความที่ยังทำไม่เสร็จ\n\nก่อน merge ให้รันเช็กอัตโนมัติแบบเร็ว ๆ ทำให้เข้มงวด: คีย์ขาดใน locales ต่าง ๆ, คีย์ไม่ได้ใช้, ความไม่ตรงกันของ placeholder (ขาด `{count}`, `{date}`, หรือวงเล็บผิด), รูปแบบพหูพจน์ที่ไม่ถูกต้องสำหรับภาษาที่รองรับ, และการ override โดยไม่ได้ตั้งใจ\n\nสุดท้าย ให้ทำ UI pass สั้น ๆ ในอย่างน้อยหนึ่ง locale ที่ไม่ใช่ค่าเริ่มต้น เลือกภาษาที่มีสตริงยาวกว่า (มักเป็นเยอรมันหรือฝรั่งเศส) เพื่อจับปัญหา overflow ปุ่มที่ถูกตัด และการตัดบรรทัดที่ไม่ดี ถ้า UI Vue 3 ของคุณถูกสร้างหรือดูแลร่วมกับส่วนอื่นของผลิตภัณฑ์ (เช่น แอป Vue3 ที่ผลิตโดย AppMaster) ขั้นตอนนี้ยังสำคัญเพราะเลย์เอาต์เปลี่ยนตามฟีเจอร์\n\nปฏิบัติต่อขั้นตอนเหล่านี้เป็นคำจำกัดความของ "เสร็จ" สำหรับทุกฟีเจอร์ที่เพิ่มข้อความ\n\n## ข้อผิดพลาดทั่วไปที่ทีมมักทำซ้ำ\n\nวิธีที่เร็วที่สุดที่จะทำให้ localization เจ็บปวดคือการมองคีย์ i18n เป็นแค่ "สตริง" หลังจากมีคีย์เป็นร้อย พฤติกรรมเล็ก ๆ จะกลายเป็นบั๊กในโปรดักชัน\n\n### คีย์ที่ลอย เปลี่ยนความหมาย หรื่อโกหก\n\nคำพิมพ์ผิดและความต่างตัวพิมพ์เป็นสาเหตุคลาสสิกของข้อความหาย: `checkout.title` ที่นึง, `Checkout.title` ที่นึง มันดูโอเคใน code review แล้ว fallback ภาษาอื่นจะถูกส่งออกเงียบ ๆ\n\nปัญหาอีกอย่างคือการใช้คีย์เดียวกันสำหรับความหมายต่างกัน “Open” อาจหมายถึง “Open ticket” ในหน้าซัพพอร์ต และ “Open now” ในหน้าร้าน ถ้าใช้คีย์เดียว หนึ่งในหน้าจะผิดในภาษาอื่น ๆ และนักแปลจะต้องเดา\n\nกฎง่าย ๆ ช่วยได้: หนึ่งคีย์ เท่ากับ หนึ่งความหมาย ถ้าความหมายเปลี่ยน ให้สร้างคีย์ใหม่ แม้ข้อความภาษาอังกฤษจะเหมือนกัน\n\n### ปัญหาเลย์เอาต์จากสมมติฐาน "รูปแบบเป็นสตริง"\n\nทีมมักฝังเครื่องหมายวรรคตอน ช่องว่าง หรือ HTML ลงในคำแปล นั่นใช้ได้จนกว่าภาษาจะต้องการเครื่องหมายต่างกัน หรือ UI ของคุณจะ escape หรือเรนเดอร์ markup แตกต่างกัน เก็บการตัดสินใจเรื่อง markup ไว้ในเทมเพลต และให้ข้อความเอาไว้แค่ข้อความ\n\nปัญหาแอบซ่อนในมือถือ ป้ายที่พอดีในอังกฤษอาจขึ้นบรรทัดสามในเยอรมัน หรือล้นในไทย หากคุณทดสอบแค่ขนาดหน้าจอเดียว คุณจะไม่เจอ\n\nเฝ้าดูผู้ทำผิดซ้ำ ๆ: สมมติรูปแบบคำอังกฤษเมื่อใส่ตัวแปร (ชื่อ จำนวน วันที่), สร้างข้อความโดยการต่อชิ้นแทนข้อความเดี่ยว, ลืมทดสอบค่าที่ยาว (ชื่อสินค้า ที่อยู่ รายละเอียดข้อผิดพลาด), ปล่อยด้วย silent fallback ที่ทำให้คีย์หายดู "โอเค" ในอังกฤษ, และคัดลอกวางคีย์แล้วแก้แค่ค่าภาษาอังกฤษ\n\nถ้าคุณอยากให้ workflow Vue 3 i18n คงที่เมื่อมีคีย์ 500+ ให้ปฏิบัติต่อคีย์เหมือน API ของคุณ: คงที่ เฉพาะ และผ่านการทดสอบเหมือนส่วนอื่น ๆ\n\n## ขั้นตอน QA ที่จับคำแปลหายตั้งแต่ต้น\n\nคำแปลหายง่ายต่อการพลาดเพราะแอปยัง “ทำงาน” อยู่ มันแค่ fallback ไปที่คีย์ หรือ locale ผิด หรือสตริงว่าง ปฏิบัติต่อความครอบคลุมการแปลเหมือนการทดสอบ: คุณต้องการผลตอบกลับเร็วก่อนเข้าถึงโปรดักชัน\n\n### เช็กอัตโนมัติ (รันทุก PR)\n\nเริ่มด้วยเช็กที่ทำให้ build fail ไม่ใช่แค่พิมพ์เตือนแล้วไม่มีใครอ่าน\n\n- สแกนโค้ดสำหรับ `$t('...')` และ `t('...')` แล้วยืนยันว่าทุกคีย์ที่ใช้มีใน base locale\n- เปรียบเทียบชุดคีย์ข้าม locales และ fail ถ้า locale ใดขาดคีย์ (ยกเว้นคีย์ที่อยู่ใน exception list สั้น ๆ และตรวจสอบแล้ว เช่น "en-only legal notes")\n- ติดธงคีย์ร้างที่มีในไฟล์ locale แต่ไม่เคยถูกใช้\n- ตรวจสอบไวยากรณ์ข้อความ (placeholder, บล็อก ICU/พหูพจน์) ข้อความที่ผิดพลาดเดียวอาจทำให้หน้าเพจแครชตอนรันไทม์\n- ถือการมีคีย์ซ้ำหรือตัวพิมพ์ไม่สอดคล้องเป็นข้อผิดพลาด\n\nเก็บ exception list ให้สั้นและมีเจ้าของ ทีมต้องเป็นผู้ดูแล ไม่ใช่ให้ผ่าน CI แบบใดก็ได้\n\n### เช็ก runtime และเช็กแบบมองเห็น (สเตจ)\n\nแม้มี CI คุณก็ยังต้องมีตาข่ายในสเตจ เพราะเส้นทางผู้ใช้จริงกระตุ้นสตริงที่คุณลืมว่ามันไดนามิก\n\nเปิด logging สำหรับ missing-translation ในสเตจและรวมบริบทพอให้แก้ได้เร็ว: locale, route, ชื่อคอมโพเนนต์ (ถ้ามี), และคีย์ที่หาย ทำให้มันดัง หากมันง่ายจะถูกมองข้ามก็จะถูกมองข้ามจริง ๆ\n\nเพิ่ม pseudo-locale และใช้มันสำหรับการเช็ก UI แบบเร็ว วิธีง่าย ๆ คือเปลี่ยนแต่ละสตริงให้ยาวขึ้นและใส่เครื่องหมายเพื่อทำให้ปัญหาเลย์เอาต์เด่น เช่น: `[!!! 𝗧𝗲𝘅𝘁 𝗲𝘅𝗽𝗮𝗻𝗱𝗲𝗱 !!!]` วิธีนี้จับปุ่มที่ถูกตัด หัวตารางที่แตก และช่องว่างที่หายก่อนปล่อย\n\nสุดท้าย ทำ spot check สั้น ๆ ก่อนปล่อย โดยดู flow ที่สำคัญ 2-3 locale: ลงชื่อเข้าใช้ เช็คเอาต์/ชำระเงิน การตั้งค่าหลัก และฟีเจอร์ใหม่ที่ปล่อย นี่คือที่ที่คุณจับข้อผิดพลาดแบบ “แปลแล้ว แต่ placeholder ผิด”\n\n## การเพิ่มภาษาใหม่และการเปลี่ยนแปลงข้อความต่อเนื่อง\n\nการเพิ่มภาษาใหม่จะยุ่งถ้าคุณมองเป็นแค่ "งานแปล" แทนที่จะเป็นการปล่อยผลิตภัณฑ์เล็ก ๆ วิธีง่ายที่สุดเพื่อให้ workflow Vue 3 i18n ของคุณนิ่งคือทำให้แอป build ได้แม้ locale ยังไม่สมบูรณ์ แต่ทำให้ช่องว่างเห็นได้ชัดก่อนผู้ใช้เห็น\n\nเมื่อเพิ่ม locale ใหม่ ให้เริ่มโดยสร้างโครงสร้างไฟล์เดียวกับ source locale (มักเป็น `en`) อย่าแปลก่อน สร้างโครงสร้างก่อน\n\n- สร้างโฟลเดอร์/ไฟล์ locale ใหม่พร้อมคีย์ครบชุดคัดลอกจาก source\n- ทำเครื่องหมายค่าเป็น placeholder TODO เพื่อให้สตริงที่ขาดเห็นได้ใน QA\n- เพิ่ม locale ใน language switcher ก็ต่อเมื่อพื้นฐานพอใช้ได้\n- รันการตรวจทีละหน้าจอเพื่อจับปัญหาเลย์เอาต์ (คำยาว การตัดบรรทัด)\n\nคำแปลมักมาช้ากว่า ดังนั้นตัดสินใจก่อนว่า "partial" สำหรับผลิตภัณฑ์ของคุณหมายถึงอะไร ถ้าฟีเจอร์เป็นหน้าลูกค้า ให้พิจารณาใช้ feature flag เพื่อให้ฟีเจอร์และสตริงของมันปล่อยพร้อมกัน ถ้าต้องปล่อยโดยไม่มีคำแปลครบ ให้เลือก fallback ชัดเจน (เช่น อังกฤษ) แทนป้ายว่าง แต่ทำให้ดังในสเตจ\n\nการแก้ข้อความเป็นที่ทีมทำคีย์พัง หากคุณเปลี่ยนคำ ให้รักษาคีย์ให้คงที่ คีย์ควรบรรยายเจตนา ไม่ใช่ประโยคเป๊ะ ๆ เก็บการเปลี่ยนชื่อคีย์ไว้เมื่อความหมายเปลี่ยนจริง ๆ และทำด้วยการมิเกรชันที่ควบคุมได้\n\nเพื่อหลีกเลี่ยง "สตริงซอมบี้" ให้ deprecate คีย์โดยตั้งใจ: ทำเครื่องหมายคีย์เป็น deprecated พร้อมวันที่และคำแนะนำเปลี่ยน ใช้มันหนึ่งรอบปล่อย แล้วลบออกหลังยืนยันว่าไม่มีการอ้างอิงแล้ว\n\nเก็บบันทึกคำแปลใกล้คีย์ ถ้า JSON ของคุณใส่คอมเมนต์ไม่ได้ ให้เก็บบันทึกในเอกสารคู่หรือไฟล์ metadata ข้างเคียง (เช่น "ใช้บนหน้าจอ checkout success") สิ่งนี้มีประโยชน์เมื่อแอป Vue 3 ของคุณถูกสร้างจากเครื่องมืออย่าง AppMaster และหลายคนแตะข้อความและ UI\n\n## ตัวอย่าง: ปล่อยฟีเจอร์ที่มีสตริงใหม่ 60 ข้อ\n\nสปรินท์หนึ่ง ทีมปล่อยสามอย่างพร้อมกัน: หน้า Settings ใหม่ หน้าบิลลิ่ง และเทมเพลตอีเมลสามฉบับ (receipt, payment failed, trial ending) นั่นคือประมาณ 60 สตริง นี่คือจุดที่ i18n มักเริ่มยุ่ง\n\nทีมตกลงจัดกลุ่มคีย์ตามฟีเจอร์ แล้วตามพื้นผิว ฟีเจอร์ใหม่แต่ละตัวมีไฟล์ใหม่ และคีย์ตามรูปแบบเดียวกันทั่วทั้งโปรเจกต์: `feature.area.element`\n\njs // settings "settings.profile.title": "Profile", "settings.security.mfa.enable": "Enable two-factor authentication",

// billing "billing.plan.current": "Current plan", "billing.invoice.count": "{count} invoice | {count} invoices",

// email "email.receipt.subject": "Your receipt", "email.payment_failed.cta": "Update payment method" ```\n\nก่อนเริ่มงานแปล สตริงพหูพจน์จะถูกทดสอบด้วยค่าจริง ไม่ใช่การเดา สำหรับ billing.invoice.count QA จะเช็ก 0, 1, 2 และ 5 โดยใช้ข้อมูลที่ seed ไว้ (หรือ toggle ง่าย ๆ ใน dev) เพื่อจับกรณีที่ไม่เหมาะสม เช่น "0 invoice"\n\nQA แล้วรัน flow โฟกัสที่มักเผยคีย์หาย: เปิด Settings และ Billing คลิกทุกแท็บหนึ่งครั้ง ทริกเกอร์เทมเพลตอีเมลแต่ละฉบับในสเตจด้วยบัญชีทดสอบ รันแอปด้วย locale ที่ไม่ใช่ค่าเริ่มต้น และ fail build ถ้ามีคำเตือน missing-translation ใน logs\n\nในสปรินท์นี้ QA พบคีย์หายสองรายการ: ป้ายหนึ่งบนหน้าบิลลิ่ง และ subject ของอีเมลหนึ่งรายการ ทีมแก้ก่อนปล่อย\n\nเมื่อจะตัดสินใจบล็อกการปล่อยหรือยอมให้ fallback ให้ใช้กฎง่าย ๆ: หน้าลูกค้าและอีเมลธุรกรรมบล็อกการปล่อย ข้อความ admin ความเสี่ยงต่ำสามารถ fallback ไปยังภาษาดีฟอลต์ได้ชั่วคราว แต่ต้องมี ticket และกำหนดเวลาแน่ชัด\n\n## ขั้นตอนถัดไปและเช็คลิสต์ปล่อยง่าย ๆ\n\nworkflow Vue 3 i18n จะนิ่งเมื่อคุณปฏิบัติต่อคำแปลเหมือนโค้ด: เพิ่มมันแบบเดียวทุกครั้ง ทดสอบ และเก็บสถิติ\n\n### เช็คลิสต์ปล่อย (5 นาที ก่อน merge)\n\n- คีย์: ตามรูปแบบการตั้งชื่อและเว้นขอบเขตชัดเจน (หน้า, ฟีเจอร์, คอมโพเนนต์)\n- พหูพจน์: ยืนยันว่าพหูพจน์แสดงผลถูกต้องอย่างน้อยในหนึ่งภาษาที่มีกฎพหูพจน์หลายแบบ\n- ตัวแปร: ตรวจสอบว่าตัวแปรมีครบ ชื่อเหมือนกันทุกที่ และดูถูกต้องด้วยข้อมูลจริง\n- Fallback: ยืนยันพฤติกรรมเมื่อคีย์หายตรงกับนโยบายของคุณ\n- หน้าจอ: spot-check หน้าจอที่มีโอกาสพังสูง (ตาราง, toast, modal, empty state)\n\n### ตัดสินใจว่าจะวัดอะไร (เพื่อให้ปัญหาโผล่เร็ว)\n\nเลือกตัวเลขง่าย ๆ แล้วทบทวนเป็นประจำ: อัตราคีย์หายในรันทดสอบ, จำนวนสตริงที่ยังไม่แปลใน locales ที่ไม่ใช่ค่าเริ่มต้น, และจำนวนคีย์ที่ไม่ได้ใช้ (สตริงที่ไม่มีที่อ้างอิงอีกต่อไป) ติดตามต่อ release ถ้าได้ เพื่อเห็นแนวโน้มไม่ใช่แค่ความผิดพลาดครั้งเดียว\n\nเขียนขั้นตอนเป๊ะ ๆ สำหรับการเพิ่มสตริง อัปเดตคำแปล และยืนยันผล เก็บให้สั้น และใส่ตัวอย่างชื่อคีย์และการใช้พหูพจน์ ผู้ร่วมงานใหม่ควรทำตามได้โดยไม่ต้องถาม\n\nถ้าคุณสร้างเครื่องมือภายใน AppMaster (appmaster.io) อาจเป็นวิธีปฏิบัติจริงที่ช่วยรักษาความสอดคล้องของข้อความ UI และคีย์คำแปลข้ามแอป Vue3 web และมือถือได้ เพราะทุกอย่างถูกจัดการในที่เดียว\n\nกำหนดงานเล็ก ๆ เกี่ยวกับ i18n ทุกสปรินท์: ลบคีย์ตาย แก้ placeholder ไม่สอดคล้อง และรีวิวการพลาดล่าสุด งานทำความสะอาดเล็ก ๆ ดีกว่าการล่าคำแปลฉุกเฉินในโปรดักชัน

ง่ายต่อการเริ่มต้น
สร้างบางสิ่งที่ น่าทึ่ง

ทดลองกับ AppMaster ด้วยแผนฟรี
เมื่อคุณพร้อม คุณสามารถเลือกการสมัครที่เหมาะสมได้

เริ่ม