如何将next-intl与Crowdin JS SDK进行对接?
使用next-intl结合Crowdin JS SDK实现翻译内容拉取与实时更新
1. 安装依赖
首先安装所需的npm包:
npm install crowdin-api-client next-intl # 或使用yarn yarn add crowdin-api-client next-intl
2. 初始化Crowdin客户端
创建一个crowdin-client.js文件,配置Crowdin API客户端(替换为你的项目ID和API令牌):
const { CrowdinApi } = require('crowdin-api-client'); // 初始化Crowdin客户端 const crowdin = new CrowdinApi({ token: 'YOUR_CROWDIN_API_TOKEN', projectId: 'YOUR_CROWDIN_PROJECT_ID' }); module.exports = crowdin;
3. 编写翻译拉取脚本
创建一个fetch-translations.js脚本,用于从Crowdin下载所有语言的翻译文件并保存到next-intl的本地化目录(默认是public/locales):
const crowdin = require('./crowdin-client'); const fs = require('fs'); const path = require('path'); // 定义本地化文件存储目录 const localesDir = path.join(process.cwd(), 'public', 'locales'); // 确保目录存在 if (!fs.existsSync(localesDir)) { fs.mkdirSync(localesDir, { recursive: true }); } async function downloadTranslations() { try { // 获取项目的目标语言列表 const { data: languages } = await crowdin.languages.listProjectLanguages(); // 遍历每个语言,下载翻译文件 for (const lang of languages) { const langDir = path.join(localesDir, lang.code); if (!fs.existsSync(langDir)) { fs.mkdirSync(langDir); } // 下载翻译文件(假设你的源文件是messages.json,根据实际调整) const translation = await crowdin.translations.downloadProjectTranslation({ targetLanguageId: lang.id, exportPattern: '/messages.json' }); // 将翻译内容写入本地文件 fs.writeFileSync( path.join(langDir, 'messages.json'), JSON.stringify(translation.data, null, 2) ); console.log(`已更新语言 ${lang.code} 的翻译`); } } catch (error) { console.error('拉取翻译失败:', error); } } // 执行拉取 downloadTranslations();
4. 集成到next-intl实现实时更新
客户端定时轮询更新
在你的React组件中,可以通过useEffect定时触发翻译拉取,并更新next-intl的上下文:
'use client'; import { useRouter } from 'next/navigation'; import { useLocale, useMessages } from 'next-intl'; import { useEffect, useState } from 'react'; async function fetchLatestMessages(locale) { // 调用API路由获取最新翻译(避免客户端暴露API令牌) const res = await fetch(`/api/fetch-translations?locale=${locale}`); return res.json(); } export default function TranslatedComponent() { const router = useRouter(); const locale = useLocale(); const [messages, setMessages] = useState(useMessages()); useEffect(() => { // 每5分钟轮询一次(可根据需求调整间隔) const interval = setInterval(async () => { const latestMessages = await fetchLatestMessages(locale); setMessages(latestMessages); // 触发路由刷新以应用新翻译 router.refresh(); }, 300000); return () => clearInterval(interval); }, [locale, router]); return ( <div> <h1>{messages.helloWorld}</h1> </div> ); }
服务端API路由(安全拉取翻译)
创建app/api/fetch-translations/route.js,在服务端执行翻译拉取:
import crowdin from '@/crowdin-client'; import { NextResponse } from 'next/server'; export async function GET(request) { const { searchParams } = new URL(request.url); const locale = searchParams.get('locale'); if (!locale) { return NextResponse.json({ error: '缺少locale参数' }, { status: 400 }); } try { // 获取对应语言的翻译 const translation = await crowdin.translations.downloadProjectTranslation({ targetLanguageId: locale, exportPattern: '/messages.json' }); return NextResponse.json(translation.data); } catch (error) { return NextResponse.json({ error: '获取翻译失败' }, { status: 500 }); } }
5. 进阶:通过Crowdin Webhook实现即时更新
如果需要更高效的实时更新,可以配置Crowdin的Webhook:
- 在Crowdin项目设置中添加Webhook,触发条件选择「翻译完成」或「翻译更新」
- 指向你的Next.js API路由(如
/api/webhook/crowdin) - 在API路由中触发
downloadTranslations函数,更新本地翻译文件,再通过WebSocket或其他方式通知客户端刷新
内容的提问来源于stack exchange,提问作者Tomislav Knežević
相关产品推荐
相关产品推荐

