วิธีการนำการทำให้รองรับหลายภาษา (internationalization) มาใช้ในแอป Next.js ที่ใช้ App Router
ทำให้แอปพลิเคชัน React ของคุณเข้าถึงผู้ใช้ได้มากขึ้นและขยายไปสู่ตลาดใหม่ด้วยการทำให้รองรับหลายภาษา (i18n)
เมื่อโลกมีการเป็นสากลมากขึ้น ก็ยิ่งสำคัญขึ้นสำหรับนักพัฒนาเว็บที่จะสร้างแอปพลิเคชันที่ตอบสนองผู้ใช้จากประเทศและวัฒนธรรมที่หลากหลาย หนึ่งในวิธีสำคัญในการบรรลุเป้าหมายนี้คือการทำให้รองรับสากล (internationalization, i18n) ซึ่งช่วยให้คุณปรับแอปพลิเคชันให้รองรับภาษาต่าง ๆ สกุลเงิน และรูปแบบวันที่ได้.
ในบทความนี้ เราจะสำรวจวิธีการเพิ่มการรองรับสากลให้กับแอป React Next.js ของคุณ โดยมีการเรนเดอร์ฝั่งเซิร์ฟเวอร์ TL;DR: ดูตัวอย่างฉบับเต็มที่นี่.
คำแนะนำนี้สำหรับแอปพลิเคชัน Next.js ที่ใช้ App Router.
หากคุณกำลังใช้ Pages Router, ดูคำแนะนำนี้แทน.
ขั้นตอนที่ 1: ติดตั้งไลบรารี i18n
ในการเพิ่มการรองรับหลายภาษา (internationalization) ในแอป Next.js ของคุณ เราจะเริ่มด้วยการเลือกไลบรารี i18n มีไลบรารียอดนิยมหลายตัว รวมถึง next-intl. อย่างไรก็ตาม ในตัวอย่างนี้ เราจะใช้ TacoTranslate.
TacoTranslate จะทำการแปลสตริงของคุณเป็นภาษาใดก็ได้โดยอัตโนมัติโดยใช้ AI ขั้นสูง และช่วยให้คุณไม่ต้องยุ่งยากกับการจัดการไฟล์ JSON ที่น่าเบื่อ
มาติดตั้งโดยใช้ npm ในเทอร์มินัลของคุณ:
npm install tacotranslateขั้นตอนที่ 2: สร้างบัญชี TacoTranslate ฟรี
ตอนนี้เมื่อคุณติดตั้งโมดูลเรียบร้อยแล้ว ถึงเวลาสร้างบัญชี TacoTranslate โครงการแปล และคีย์ API ที่เกี่ยวข้องแล้ว สร้างบัญชีที่นี่ บริการนี้ฟรี และ ไม่จำเป็นต้องเพิ่มบัตรเครดิต.
ภายในอินเทอร์เฟซของแอป TacoTranslate ให้สร้างโปรเจ็กต์ แล้วไปที่แท็บ API keys ของโปรเจ็กต์นั้น สร้างคีย์ read หนึ่งชุด และคีย์ read/write หนึ่งชุด เราจะบันทึกคีย์เหล่านั้นเป็นตัวแปรสภาพแวดล้อม คีย์ read คือสิ่งที่เราเรียกว่า public และคีย์ read/write คือ secret ตัวอย่างเช่น คุณอาจเพิ่มคีย์เหล่านี้ลงในไฟล์ .env ที่อยู่ที่รูทของโปรเจ็กต์ของคุณ
TACOTRANSLATE_PUBLIC_API_KEY=123456
TACOTRANSLATE_SECRET_API_KEY=789010โปรดอย่าให้คีย์ API ความลับ read/write รั่วไหลไปยังสภาพแวดล้อมการผลิตฝั่งไคลเอนต์.
เราจะเพิ่มตัวแปรสภาพแวดล้อมอีกสองตัวด้วย: TACOTRANSLATE_DEFAULT_LOCALE และ TACOTRANSLATE_ORIGIN.
TACOTRANSLATE_DEFAULT_LOCALE: รหัส locale ที่ใช้เป็นค่าเริ่มต้น (fallback). ในตัวอย่างนี้เราจะตั้งเป็นenสำหรับภาษาอังกฤษ.TACOTRANSLATE_ORIGIN: “โฟลเดอร์” ที่เก็บสตริงของคุณ เช่น URL ของเว็บไซต์ของคุณ. อ่านเพิ่มเติมเกี่ยวกับ origins ได้ที่นี่
TACOTRANSLATE_DEFAULT_LOCALE=en
TACOTRANSLATE_ORIGIN=your-website-url.comขั้นตอนที่ 3: การตั้งค่า TacoTranslate
ในการผสาน TacoTranslate เข้ากับแอปของคุณ คุณจะต้องสร้างไคลเอนต์โดยใช้คีย์ API ที่กล่าวไว้ก่อนหน้านี้ ตัวอย่างเช่น สร้างไฟล์ชื่อ /tacotranslate-client.js.
const {default: createTacoTranslateClient} = require('tacotranslate');
const tacoTranslate = createTacoTranslateClient({
apiKey:
process.env.TACOTRANSLATE_SECRET_API_KEY ??
process.env.TACOTRANSLATE_PUBLIC_API_KEY ??
process.env.TACOTRANSLATE_API_KEY,
projectLocale:
process.env.TACOTRANSLATE_IS_PRODUCTION === 'true'
? process.env.TACOTRANSLATE_PROJECT_LOCALE
: undefined,
});
module.exports = tacoTranslate;เราจะกำหนด TACOTRANSLATE_API_KEY และ TACOTRANSLATE_PROJECT_LOCALE ให้โดยอัตโนมัติในเร็ว ๆ นี้.
การสร้าง client ในไฟล์แยกจะทำให้เรียกใช้งานซ้ำได้ง่ายขึ้นในภายหลัง. getLocales เป็นเพียงฟังก์ชันอรรถประโยชน์ที่มีการจัดการข้อผิดพลาดในตัวเล็กน้อย. ตอนนี้ ให้สร้างไฟล์ชื่อ /app/[locale]/tacotranslate.tsx, ซึ่งเราจะนำตัวให้บริการของ TacoTranslate มาใช้งาน.
'use client';
import React, {type ReactNode} from 'react';
import {
type TranslationContextProperties,
TacoTranslate as ImportedTacoTranslate,
} from 'tacotranslate/react';
import tacoTranslateClient from '@/tacotranslate-client';
export default function TacoTranslate({
locale,
origin,
localizations,
children,
}: TranslationContextProperties & {
readonly children: ReactNode;
}) {
return (
<ImportedTacoTranslate
client={tacoTranslateClient}
locale={locale}
origin={origin}
localizations={localizations}
>
{children}
</ImportedTacoTranslate>
);
}สังเกต 'use client'; ซึ่งระบุว่านี่เป็นคอมโพเนนต์ฝั่งไคลเอนต์.
เมื่อตัวจัดเตรียมบริบท (context provider) พร้อมใช้งานแล้ว ให้สร้างไฟล์ชื่อ /app/[locale]/layout.tsx, ซึ่งเป็นเลย์เอาต์หลักในแอปพลิเคชันของเรา โปรดทราบว่าเส้นทางนี้มีโฟลเดอร์ที่ใช้ Dynamic Routes, โดยที่ [locale] เป็นพารามิเตอร์แบบไดนามิก
import React, {type ReactNode} from 'react';
import {type Locale, isRightToLeftLocaleCode} from 'tacotranslate';
import './global.css';
import tacoTranslateClient from '@/tacotranslate-client';
import TacoTranslate from './tacotranslate';
export async function generateStaticParams() {
const locales = await tacoTranslateClient.getLocales();
return locales.map((locale) => ({locale}));
}
type RootLayoutParameters = {
readonly params: Promise<{locale: Locale}>;
readonly children: ReactNode;
};
export default async function RootLayout({params, children}: RootLayoutParameters) {
const {locale} = await params;
const origin = process.env.TACOTRANSLATE_ORIGIN;
const localizations = await tacoTranslateClient.getLocalizations({
locale,
origins: [origin /* , other origins to fetch */],
});
return (
<html lang={locale} dir={isRightToLeftLocaleCode(locale) ? 'rtl' : 'ltr'}>
<body>
<TacoTranslate
locale={locale}
origin={origin}
localizations={localizations}
>
{children}
</TacoTranslate>
</body>
</html>
);
}สิ่งแรกที่ต้องสังเกตที่นี่คือเราใช้พารามิเตอร์ Dynamic Route [locale] เพื่อดึงการแปลสำหรับภาษานั้น นอกจากนี้ generateStaticParams ยังช่วยให้แน่ใจว่าโค้ด locale ทั้งหมดที่คุณเปิดใช้งานสำหรับโปรเจ็กต์ของคุณจะถูกพรีเรนเดอร์
ตอนนี้มาสร้างหน้าแรกของเรากันเถอะ! สร้างไฟล์ชื่อ /app/[locale]/page.tsx.
import React from 'react';
import {Translate} from 'tacotranslate/react';
export const revalidate = 60;
export default async function Page() {
return (
<Translate string="Hello, world!" />
);
}สังเกตตัวแปร revalidate ซึ่งแจ้งให้ Next.js สร้างเพจใหม่หลังจาก 60 วินาที เพื่อให้การแปลของคุณทันสมัยอยู่เสมอ
ขั้นตอนที่ 4: การใช้งานการเรนเดอร์ฝั่งเซิร์ฟเวอร์
TacoTranslate รองรับการเรนเดอร์ฝั่งเซิร์ฟเวอร์ (server-side rendering) ซึ่งช่วยปรับปรุงประสบการณ์ผู้ใช้เป็นอย่างมากโดยแสดงเนื้อหาที่แปลแล้วทันที แทนที่จะเกิดการกระพริบของเนื้อหาที่ยังไม่ได้แปลก่อน นอกจากนี้ เรายังสามารถข้ามการเรียกเครือข่ายจากฝั่งไคลเอนต์ได้ เพราะเรามีคำแปลที่ต้องการสำหรับหน้าที่ผู้ใช้กำลังดูอยู่แล้ว
ในการตั้งค่าการเรนเดอร์ฝั่งเซิร์ฟเวอร์ ให้สร้างหรือแก้ไข /next.config.js:
const withTacoTranslate = require('tacotranslate/next/config').default;
const tacoTranslateClient = require('./tacotranslate-client');
module.exports = async () => {
const config = await withTacoTranslate(
{},
{
client: tacoTranslateClient,
isProduction:
process.env.TACOTRANSLATE_ENV === 'production' ||
process.env.VERCEL_ENV === 'production' ||
(!(process.env.TACOTRANSLATE_ENV || process.env.VERCEL_ENV) &&
process.env.NODE_ENV === 'production'),
}
);
// NOTE: Remove i18n from config when using the app router
return {...config, i18n: undefined};
};ปรับการตรวจสอบ isProduction ให้เหมาะกับการตั้งค่าของคุณ หาก true, TacoTranslate จะเปิดเผยคีย์ API แบบสาธารณะ หากเราอยู่ในสภาพแวดล้อมท้องถิ่น ทดสอบ หรือสเตจ (isProduction is false) เราจะใช้คีย์ API แบบลับ read/write เพื่อให้แน่ใจว่าสตริงใหม่ถูกส่งไปเพื่อการแปล
เพื่อให้การกำหนดเส้นทางและการเปลี่ยนเส้นทางทำงานตามที่คาดไว้ เราจะต้องสร้างไฟล์ชื่อ /middleware.ts. โดยใช้ Middleware, เราสามารถเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าที่แสดงเป็นภาษาที่พวกเขาเลือกได้.
import {type NextRequest} from 'next/server';
import {middleware as tacoTranslateMiddleware} from 'tacotranslate/next';
import tacoTranslate from '@/tacotranslate-client';
export const config = {
matcher: ['/((?!api|_next|favicon.ico).*)'],
};
export async function middleware(request: NextRequest) {
return tacoTranslateMiddleware(tacoTranslate, request);
}ตรวจสอบให้แน่ใจว่าได้ตั้งค่า matcher ให้สอดคล้องกับ เอกสาร Next.js Middleware.
บนฝั่งไคลเอนต์ คุณสามารถเปลี่ยนคุกกี้ locale เพื่อเปลี่ยนภาษาที่ผู้ใช้ต้องการ โปรดดู ตัวอย่างโค้ดฉบับสมบูรณ์ สำหรับแนวทางในการทำเช่นนี้!
ขั้นตอนที่ 5: ปรับใช้และทดสอบ!
เสร็จเรียบร้อยแล้ว! แอป React ของคุณจะถูกแปลโดยอัตโนมัติเมื่อคุณเพิ่มสตริงใดๆ ลงในคอมโพเนนต์ Translate. โปรดทราบว่าเฉพาะสภาพแวดล้อมที่มีสิทธิ์ read/write บนคีย์ API เท่านั้นที่จะสามารถสร้างสตริงใหม่เพื่อส่งไปแปลได้ เราขอแนะนำให้มีสภาพแวดล้อมสเตจที่ปิดและปลอดภัย ซึ่งคุณสามารถทดสอบแอปที่ใช้งานจริงด้วยคีย์ API แบบนั้น โดยเพิ่มสตริงใหม่ก่อนจะเปิดใช้งานจริง สิ่งนี้จะช่วยป้องกันไม่ให้ใครขโมยคีย์ API ลับของคุณ และป้องกันไม่ให้โปรเจกต์การแปลของคุณบวมขึ้นจากการเพิ่มสตริงใหม่ที่ไม่เกี่ยวข้อง
Be sure to check out the complete example over at our GitHub profile. There, you’ll also find an example of how to do this using the Pages Router! If you encounter any problems, feel free to reach out, and we’ll be more than happy to help.
TacoTranslate lets you automatically localize your React applications quickly to and from over 75 languages. Get started today!