เพิ่มหลายภาษาให้แอป Next.js ของคุณ
แปลไฟล์ locale, เนื้อหา Markdown และหน้า HTML ผ่านการเรียก API ครั้งเดียว ใช้งานร่วมกับ App Router, next-intl และการตั้งค่า i18n routing ใดๆ ได้
Next.js ให้ routing แต่ไม่ให้การแปล
Next.js App Router มีการสนับสนุน routing ตาม locale ที่ยอดเยี่ยมในตัว ไลบรารีอย่าง next-intl ทำให้การจัดการไฟล์แปลและการสลับ locale เป็นเรื่องง่าย สิ่งที่พวกเขาไม่แก้ไขคือการแปลเอง — ต้องมีคนสร้างเนื้อหาที่แปลในทุกภาษา และคนนั้นมักจะเป็นคุณ สำหรับทีมส่วนใหญ่ กระบวนการคือคัดลอก JSON ภาษาอังกฤษไปยัง DeepL แก้ไขรูปแบบที่เสียหาย วางผลลัพธ์กลับ และทำซ้ำสำหรับทุกภาษา มันช้า มีข้อผิดพลาด และไม่สามารถขยายได้
กระบวนการที่พบบ่อยที่สุดคือเขียนข้อความ UI ทั้งหมดเป็นภาษาอังกฤษในซอร์สโค้ด จากนั้นแปลไฟล์ messages.json สำหรับแต่ละภาษาที่ต้องการ ในทางทฤษฎีมันง่าย แต่ในทางปฏิบัติ การรักษาไฟล์ locale มากกว่า 10 ไฟล์ให้สอดคล้องกับการเปลี่ยนแปลงซอร์สโค้ดกลายเป็นปัญหาซ้ำๆ ทุกครั้งที่ข้อความภาษาอังกฤษเปลี่ยน ไฟล์ locale ทุกไฟล์ต้องอัปเดต เมื่อใช้ API แปลมาตรฐาน ชื่อคีย์จะเสียหาย ตัวแปรถูกแปล และโครงสร้าง JSON แตกต่างกันระหว่าง locale — ทำให้เกิดบั๊กที่ตรวจสอบยากใน runtime
PolyLingo เข้ากับการตั้งค่า i18n ของ Next.js ที่คุณมีอยู่แล้ว
ถ้าคุณใช้ next-intl หรือไลบรารี i18n อื่นๆ ข้อความของคุณก็อยู่ในรูปแบบ JSON อยู่แล้ว PolyLingo จะรับ JSON นั้น ส่งผ่านโมเดลแปล และส่งคืนสำเนาที่แปลแล้วสำหรับทุกภาษาที่ต้องการ — โดยคีย์ไม่ถูกแตะต้อง โครงสร้างซ้อนยังคงอยู่ และค่าข้อความถูกแปลอย่างถูกต้อง คุณสามารถเรียกใช้จากสคริปต์ build, webhook หรือ UI ของ PolyLingo ผลลัพธ์จะถูกวางตรงลงในไดเรกทอรี messages ของคุณ
กระบวนการ: เขียน messages.json ภาษาอังกฤษของคุณ รันสคริปต์เดียวที่เรียก API ของ PolyLingo พร้อมไฟล์ต้นทางและรหัสภาษาปลายทางทั้งหมด รับไฟล์ JSON แปลหนึ่งไฟล์ต่อภาษา โดยมีโครงสร้างเหมือนกัน เขียนแต่ละไฟล์ลงในไดเรกทอรี messages/ ของคุณ คอมมิต เสร็จสิ้น
สำหรับเว็บไซต์ที่มีเนื้อหาหนักโดยใช้ Markdown ใน CMS (Sanity, Contentful) วิธีเดียวกันนี้ใช้กับเนื้อหา: ส่งออกเป็น Markdown หรือ HTML, แปล, เขียนกลับไปยัง CMS ผ่าน API ของมัน ทั้งกระบวนการสามารถรันเป็นขั้นตอน build หรือทริกเกอร์ด้วย webhook
// This repository: frontend/scripts/translate-messages.mjs
// Chunks large namespaces (e.g. home) so the model stays within output limits.
//
// export POLYLINGO_API_KEY=pl_xxx
// npm run i18n:polylingo
//
// Writes messages/es.json, fr.json, … from messages/en.json via POST /v1/translate
// with format: "json". See MARKETING_I18N.md for options and CI notes.
//
// Minimal one-shot pattern (fine for small message files):
//
// const source = readFileSync('./messages/en.json', 'utf8')
// const { translations } = await fetch(apiUrl + '/translate', {
// method: 'POST',
// headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
// body: JSON.stringify({
// content: source, format: 'json', source: 'en',
// targets: ['es', 'fr', 'de'], model: 'standard',
// }),
// }).then((r) => r.json())
//
// for (const [lang, raw] of Object.entries(translations)) {
// const obj = typeof raw === 'string' ? JSON.parse(raw) : raw
// writeFileSync(`./messages/${lang}.json`, JSON.stringify(obj, null, 2))
// }// i18n.ts (next-intl v4)
import { getRequestConfig } from 'next-intl/server'
export const locales = [
'en', 'ar', 'bn', 'cs', 'da', 'de', 'el', 'es', 'fa', 'fi',
'fr', 'he', 'hi', 'id', 'it', 'ja', 'ko', 'ms', 'nl', 'no',
'pl', 'pt', 'ru', 'sv', 'sw', 'th', 'tr', 'uk', 'vi', 'zh',
] as const
export type Locale = (typeof locales)[number]
export default getRequestConfig(async ({ requestLocale }) => {
const locale = await requestLocale
return {
locale,
messages: (await import(`./messages/${locale}.json`)).default,
}
})// package.json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"i18n:polylingo": "node scripts/translate-messages.mjs",
"translate:build": "npm run i18n:polylingo && next build"
}
}ทำไม PolyLingo ถึงเหมาะกับ workflow i18n ของ Next.js
- ✓แปลไฟล์ messages/*.json โดยตรง — คีย์ถูกเก็บไว้เสมอ
- ✓แปลเนื้อหา Markdown สำหรับบทความบล็อกและหน้าคู่มือ
- ✓ใช้งานร่วมกับ next-intl, next-i18next และการตั้งค่าที่กำหนดเอง
- ✓REST API ผสานกับสคริปต์ build และ webhook ของ CMS
- ✓รองรับ 36 ภาษาในคำขอเดียว
- ✓ชั้นฟรี — 50,000 โทเค็นต่อเดือน
- ✓รีโปนี้ใช้ workflow จริง: npm run i18n:polylingo สร้าง locale การตลาดจาก messages/en.json (ดู MARKETING_I18N.md)
- ✓ใช้งานร่วมกับ App Router และ Pages Router
- ✓ไฟล์ผลลัพธ์พร้อมคอมมิต — ไม่ต้องจัดรูปแบบใหม่
ตั้งค่าหลายภาษาในแอป Next.js ของคุณ
ตั้งค่า next-intl กับไฟล์ข้อความภาษาอังกฤษของคุณ
ติดตั้ง next-intl และตั้งค่า i18n.ts กับ middleware เขียนข้อความ UI ทั้งหมดใน messages/en.json โครงสร้างไฟล์ตามที่แอปของคุณต้องการ — แบบแบนหรือซ้อน นี่คือแหล่งข้อมูลเดียวของคุณ
รันสคริปต์แปล
ใช้ PolyLingo JSON API จากสคริปต์ Node เล็กๆ (ดูโค้ดด้านบน) ใน monorepo นี้ รัน npm run i18n:polylingo จาก frontend/ โดยตั้งค่า POLYLINGO_API_KEY — มันจะแบ่ง namespace ใหญ่ๆ เพื่อความน่าเชื่อถือ การรันทั่วไปใช้เวลาน้อยกว่าหนึ่งนาทีสำหรับชุดการตลาดทั้งหมด
คอมมิตไฟล์ locale และดีพลอย
ไฟล์ locale ที่สร้างขึ้นเป็น JSON ที่ถูกต้องและมีโครงสร้างเหมือนกับต้นทาง คอมมิตไฟล์เหล่านี้ในรีโปของคุณ เพิ่มสคริปต์แปลใน pipeline CI เพื่อให้ locale สอดคล้องกับทุกการเปลี่ยนแปลงเนื้อหา
กรณีการใช้งานหลายภาษาใน Next.js
แอป SaaS และแดชบอร์ด
แปลไลบรารีข้อความ UI ทั้งหมดในสคริปต์รันครั้งเดียว รองรับฟีเจอร์การจัดรูปแบบของ next-intl ทั้งหมด — วันที่, ตัวเลข, พหูพจน์ — เพราะโครงสร้าง JSON ถูกเก็บไว้อย่างแม่นยำ
เว็บไซต์เนื้อหาและบล็อก
สำหรับเว็บไซต์ Next.js ที่มีเนื้อหาหนักโดยใช้ Sanity หรือ Contentful ใช้ PolyLingo แปลเนื้อหาหน้ารวมถึงข้อความ UI — API เดียวกัน รับประกันการรักษารูปแบบเหมือนกัน
อีคอมเมิร์ซที่มีตัวแปรภูมิภาค
แปลชื่อสินค้า, คำอธิบาย, หน้าหมวดหมู่ และ UI การชำระเงิน ใช้โมเดล Advanced สำหรับข้อความการตลาดที่ต้องการเสียงแบรนด์ ใช้ Standard สำหรับข้อความ UI ที่ใช้งานได้
คำถามที่พบบ่อย
ใช้งานร่วมกับ Next.js App Router ได้ไหม?
ได้ การผสาน PolyLingo เป็นเพียงสคริปต์ที่อ่านและเขียนไฟล์ JSON — ไม่มีการพึ่งพาภายในของ Next.js มันทำงานกับ App Router, Pages Router หรือเฟรมเวิร์กใดๆ ตัวอย่างการตั้งค่า next-intl ที่แสดงใช้ API v4 กับ requestLocale ซึ่งเข้ากันได้กับ Next.js 13, 14 และ 15
ถ้า messages.json ของฉันเปลี่ยนบ่อยล่ะ?
รูปแบบที่แนะนำคือเพิ่มสคริปต์แปลใน pipeline CI/CD ของคุณ โดยทริกเกอร์เมื่อ messages/en.json เปลี่ยนแปลง วิธีนี้จะทำให้ไฟล์ locale ทั้งหมดสอดคล้องกันโดยอัตโนมัติ สำหรับทีมที่มีการเปลี่ยนแปลงข้อความบ่อย วิธีนี้จะป้องกันการเบี่ยงเบนของ locale อย่างสมบูรณ์
PolyLingo ใช้งานกับ next-i18next และ next-intl ได้ไหม?
ได้ next-i18next ใช้โครงสร้าง JSON locale เดียวกัน สคริปต์แปลทำงานเหมือนกัน — ชี้ไปที่ไดเรกทอรี public/locales/en/ ของคุณและเขียนผลลัพธ์ไปยังไดเรกทอรี locale อื่นๆ ความเข้ากันได้ของรูปแบบ JSON เหมือนกัน
แล้วเนื้อหาไดนามิกที่ไม่อยู่ในไฟล์ messages ล่ะ?
เนื้อหาไดนามิก — บทความบล็อก, คำอธิบายสินค้า, เนื้อหาที่ผู้ใช้สร้าง — ควรแปลที่ชั้นข้อมูล ไม่ว่าจะใน CMS ของคุณหรือผ่านสคริปต์ build ที่ประมวลผลเนื้อหาก่อนถึง Next.js PolyLingo รองรับ Markdown, HTML และข้อความธรรมดาอย่างเท่าเทียมกันสำหรับวัตถุประสงค์นี้
ฉันจะแปลเฉพาะข้อความที่เปลี่ยนแปลงตั้งแต่รันครั้งล่าสุดได้ไหม?
การแปลแบบเพิ่มทีละส่วน (แปลเฉพาะคีย์ที่เปลี่ยน) อยู่ในแผนพัฒนา ปัจจุบันสคริปต์จะแปลไฟล์ทั้งหมดใหม่ สำหรับไฟล์ข้อความส่วนใหญ่ (ต่ำกว่า 20KB) นี่เร็วพอที่จะรันทุกครั้งที่คอมมิต สำหรับไฟล์ใหญ่ แนะนำให้แบ่งตาม namespace
มีวิธีตรวจสอบการแปลก่อนนำไปใช้จริงไหม?
รูปแบบที่แนะนำคือคอมมิตไฟล์ locale ที่แปลแล้วไปยังสาขาหรือ PR แยกเพื่อทบทวนก่อนรวมเข้ากับ main นี่เป็นแนวปฏิบัติมาตรฐานสำหรับทีมที่ต้องการตรวจสอบคุณภาพการแปลด้วยมนุษย์ PolyLingo สร้างผลลัพธ์รอบแรกที่ดี — สำหรับข้อความ UI ส่วนใหญ่ ผลลัพธ์โมเดล Standard ไม่ต้องแก้ไข
แปลไฟล์ locale แรกของคุณภายใน 5 นาที
API key ฟรี ไม่ต้องใช้บัตรเครดิต วาง JSON ข้อความของคุณและดูผลลัพธ์ทันที
รับ API key ของคุณสคริปต์แปลตั้งค่าได้ภายใน 5 นาที ชั้นฟรี — ไม่ต้องใช้บัตรเครดิต