بازگشت به وبلاگ
Terminal output showing a translation script writing de.json and fr.json, alongside a folder tree and a browser rendering the German locale route.

چگونه یک اپلیکیشن Next.js را با PolyLingo در کمتر از ۳۰ دقیقه ترجمه کنیم

By Robert

چگونه یک اپلیکیشن Next.js را با PolyLingo در کمتر از ۳۰ دقیقه ترجمه کنیم

تا پایان این آموزش، یک پروژه چندزبانه Next.js App Router عملی خواهید داشت: رشته‌ها استخراج شده در messages/en.json، فایل‌های محلی ترجمه شده برای هر زبان مورد نیاز، next-intl که فایل مناسب را برای هر مسیر ارائه می‌دهد و یک اسکریپت Node که هر زمان محتوای شما تغییر کرد می‌توانید دوباره اجرا کنید.

نیازی به ثبت‌نام در پلتفرم ترجمه نیست. هیچ هزینه ثابت برای هر زبان وجود ندارد. یک تماس API همه زبان‌های هدف شما را به‌طور همزمان مدیریت می‌کند.

آنچه نیاز دارید:

  • یک پروژه Next.js که از App Router استفاده می‌کند (Next.js 14 یا 15)
  • Node.js نسخه ۱۸ یا بالاتر
  • یک حساب رایگان PolyLingo و کلید API

مرحله ۱: کلید API PolyLingo خود را دریافت کنید (۵ دقیقه)

یک حساب رایگان در usepolylingo.com ایجاد کنید. سطح رایگان شامل ۱۰۰,۰۰۰ توکن در ماه است که برای ترجمه یک فایل محلی متوسط به بیش از ۱۰ زبان چندین بار کافی است.

وقتی وارد شدید، به API keys در داشبورد بروید و یک کلید ایجاد کنید. مقدار کامل را فقط یک بار خواهید دید، پس فوراً آن را کپی کنید.

آن را به عنوان یک متغیر محیطی به پروژه خود اضافه کنید. هرگز آن را در کنترل نسخه کامیت نکنید و هرگز در کد سمت کلاینت نمایش ندهید:

# .env.local
POLYLINGO_API_KEY="pl_کلید_شما_اینجا"

قبل از ادامه، بررسی کنید که API در دسترس است:

curl -sS "https://api.usepolylingo.com/v1/health"

باید یک پاسخ کوچک JSON با "status": "ok" دریافت کنید.


مرحله ۲: نصب next-intl و راه‌اندازی مسیرها (۱۰ دقیقه)

کتابخانه را نصب کنید:

npm install next-intl

یک فایل i18n.ts در ریشه پروژه خود ایجاد کنید. این فایل به next-intl می‌گوید کدام لوکال‌ها را پشتیبانی می‌کنید و چگونه فایل پیام مناسب را برای هر درخواست بارگذاری کند:

// i18n.ts
import { getRequestConfig } from 'next-intl/server'

export const locales = ['en', 'de', 'fr'] as const
export type Locale = (typeof locales)[number]
export const defaultLocale: Locale = 'en'

export default getRequestConfig(async ({ requestLocale }) => {
  let locale = await requestLocale
  if (!locale || !locales.includes(locale as Locale)) {
    locale = defaultLocale
  }
  return {
    locale,
    messages: (await import(`./messages/${locale}.json`)).default,
  }
})

میان‌افزار اضافه کنید تا مسیرها با پیشوند لوکال باشند:

// middleware.ts
import createMiddleware from 'next-intl/middleware'
import { locales, defaultLocale } from './i18n'

export default createMiddleware({
  locales: [...locales],
  defaultLocale,
  localePrefix: 'as-needed',
})

export const config = {
  matcher: ['/((?!api|_next|.*\..*).*)'],
}

فایل‌های صفحه خود را به زیر app/[locale]/ منتقل کنید. لایه ریشه خود را به‌روزرسانی کنید تا پارامتر locale را دریافت کند و فرزندان را با NextIntlClientProvider بپیچد:

// app/[locale]/layout.tsx
import { NextIntlClientProvider } from 'next-intl'
import { getMessages } from 'next-intl/server'

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode
  params: Promise<{ locale: string }>
}) {
  const { locale } = await params
  const messages = await getMessages()
  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  )
}

مرحله ۳: رشته‌های خود را به یک فایل پیام JSON استخراج کنید (۱۰ دقیقه)

یک پوشه messages/ در ریشه پروژه خود ایجاد کنید. یک فایل en.json با رشته‌های منبع خود اضافه کنید. next-intl از ساختار کلیدهای تو در تو استفاده می‌کند:

{
  "Home": {
    "title": "خوش آمدید",
    "cta": "شروع کنید"
  }
}

صفحات خود را به‌روزرسانی کنید تا به جای رشته‌های ثابت از useTranslations استفاده کنند:

// app/[locale]/page.tsx
import { useTranslations } from 'next-intl'

export default function HomePage() {
  const t = useTranslations('Home')
  return (
    <main>
      <h1>{t('title')}</h1>
      <button type="button">{t('cta')}</button>
    </main>
  )
}

حالا اسکریپت ترجمه را بنویسید. این اسکریپت messages/en.json را می‌خواند، آن را با format: "json" به API PolyLingo ارسال می‌کند و برای هر لوکال هدف یک فایل خروجی می‌نویسد. فلگ format: "json" به API می‌گوید ساختار کلیدها را حفظ کند و فقط مقادیر رشته‌ای را ترجمه کند — کلیدهای تو در تو، آرایه‌ها و انواع غیررشته‌ای دست نخورده باقی می‌مانند.

// scripts/translate-messages.mjs
// اجرا با: node scripts/translate-messages.mjs

import fs from 'node:fs'
import path from 'node:path'

const API_KEY = process.env.POLYLINGO_API_KEY
const API_URL = (process.env.POLYLINGO_API_URL || 'https://api.usepolylingo.com/v1').replace(/\/$/, '')
const TARGETS = ['de', 'fr'] // این آرایه را برای افزودن لوکال‌های بیشتر گسترش دهید

const enPath = path.join('messages', 'en.json')
const en = JSON.parse(fs.readFileSync(enPath, 'utf8'))

const res = await fetch(`${API_URL}/translate`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    content: JSON.stringify(en),
    format: 'json',
    targets: TARGETS,
    model: 'standard',
  }),
})

if (!res.ok) {
  const err = await res.text()
  throw new Error(`PolyLingo ${res.status}: ${err}`)
}

const { translations } = await res.json()

for (const locale of TARGETS) {
  const out = path.join('messages', `${locale}.json`)
  fs.writeFileSync(out, JSON.stringify(JSON.parse(translations[locale]), null, 2) + '\n')
  console.log('Wrote', out)
}

آن را اجرا کنید:

node scripts/translate-messages.mjs

باید خروجی‌ای مانند این ببینید:

Wrote messages/de.json
Wrote messages/fr.json

آن فایل‌ها را باز کنید و بررسی کنید. کلیدهای شما با en.json یکسان خواهند بود. فقط مقادیر رشته‌ای تغییر کرده‌اند.


مرحله ۴: تست مسیرها (۵ دقیقه)

سرور توسعه خود را راه‌اندازی کنید:

npm run dev

به http://localhost:3000 و http://localhost:3000/de مراجعه کنید. عنوان و دکمه باید به ترتیب به انگلیسی و آلمانی نمایش داده شوند. با گسترش آرایه TARGETS در اسکریپت و آرایه locales در i18n.ts لوکال‌های بیشتری اضافه کنید و سپس اسکریپت را دوباره اجرا کنید.

مصرف توکن خود را در داشبورد PolyLingo زیر Usage بررسی کنید. برای یک فایل محلی کوچک که به دو زبان ترجمه شده، چند صد توکن از سهمیه ماهانه خود استفاده کرده‌اید.


ادامه مسیر

لوکال‌های بیشتری اضافه کنید. اسکریپت یک درخواست ارسال می‌کند بدون توجه به تعداد ورودی‌های TARGETS. افزودن ژاپنی، اسپانیایی و عربی فقط یک تماس API هزینه دارد، نه سه.

آن را در CI ادغام کنید. POLYLINGO_API_KEY را به عنوان یک راز مخزن در GitHub Actions اضافه کنید و اسکریپت را به عنوان بخشی از خط لوله ساخت خود اجرا کنید. فایل‌های لوکال شما به طور خودکار هر زمان که en.json تغییر کند همگام‌سازی می‌شوند.

فرمت‌های دیگر را ترجمه کنید. همان الگوی اسکریپت برای صفحات مستندات Markdown (format: "markdown") و قالب‌های ایمیل HTML (format: "html") کار می‌کند. API ساختار را در همه موارد حفظ می‌کند.

برای پروژه‌های بزرگ‌تر از endpoint دسته‌ای استفاده کنید. اگر چندین فایل JSON جداگانه دارید (مثلاً یکی برای هر بخش ویژگی)، POST /translate/batch تا ۱۰۰ مورد را در یک درخواست می‌پذیرد، هر کدام با id و format مخصوص به خود.


رایگان امتحان کنید

سطح رایگان PolyLingo شامل ۱۰۰,۰۰۰ توکن در ماه است. کارت اعتباری لازم نیست.

curl -sS -X POST "https://api.usepolylingo.com/v1/translate" \
  -H "Authorization: Bearer $POLYLINGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "{\"Home\":{\"title\":\"خوش آمدید\",\"cta\":\"شروع کنید\"}}",
    "format": "json",
    "targets": ["de", "fr", "es", "ja"]
  }'

کلید API خود را دریافت کنید