돌아가기
#takeoff
#i18n
#Next.js

Takeoff. 서비스 다국어 지원하기 (feat. Next.js 15)

Takeoff. 서비스 다국어 지원하기 (feat. Next.js 15)

서비스 언어를 한국어만 지원하도록 설정하기에는 아쉬움이 남아서 영어를 추가로 지원하기로 했다.

현재 상황에서 다국어 지원을 하기 위해 필요한 것은 다음과 같다.

  1. 하드코딩된 한국어 문자열을 다국어 딕셔너리로 변환하는 작업
  2. AI가 생성한 포스트를 영어로 번역 후 데이터베이스에 저장

프론트엔드로 Next.js 15를 사용하고 있기 때문에 다국어 지원을 위해 몇가지 라이브러리를 찾아보았다.

Next.js 15에서 다국어 지원하기

라이브러리를 선택하기 위해 최신 Next.js와 완전히 호환되는지, 라이브러리가 가벼운지, 문서가 잘 정리되어 있는지를 고려했다.

next-18next, next-international, lingui 등 다양한 라이브러리가 있었지만 그 중 next-intl 가 앞서 언급한 조건을 모두 만족하는 라이브러리이기 때문에 선택했다.

국제화 기능을 사용하는 방식에는 라우팅 방식과 논라우팅 방식이 있는데 차이는 다음과 같다.

구분라우팅 방식논라우팅 방식
구분 방식/en/... 접두사 기반 라우팅 또는 en.examples.com 도메인 기반 라우팅사용자 설정에 따라 언어 지정 (헤더나 쿠키 등)
Next.js의 dynamic routes를 사용앱 구조를 변경할 필요 없음

이전에는 국제화를 할 때 논라우팅 방식을 많이 사용했기 때문에 이번 프로젝트에서는 접두사 기반 라우팅을 사용하기로 했다.

시작하기

설정은 공식문서를 따라 진행했다.

next-intluseTranslations 훅을 제공하기 때문에 각 언어를 구분하여 문자열을 관리할 수 있다.

비동기 컴포넌트의 경우에는 getTranslations 함수를 사용하여 문자열을 가져올 수 있다.

국제화를 고려하지 않은 하드코딩 된 문자열 마이그레이션하기

처음에 서비스를 만들 때 국제화를 전혀 고려하지 않았기 때문에 모든 문자열이 하드코딩 되어 있는 상황이었다.

예시 코드

tsx
import Link from "next/link";
import Background from "./Background";
 
export default function BenchmarkBanner() {
  return (
    <Link
      className="relative w-full h-24 overflow-hidden flex flex-col items-center justify-center bg-purple-800/20
        rounded-3xl cursor-pointer border-2 border-purple-800/20 shadow-2xl
        hover:border-purple-800/20 hover:shadow-purple-800/20 transition-all duration-150
    "
      href="/benchmarking"
    >
      <h1
        className="text-3xl text-purple-200/90 z-10
      text-shadow-[rgba(255, 255, 255, 0.5)]"
      >
        인공지능 벤치마크
      </h1>
      <p className="text-xs text-purple-100 z-10">
        클릭하여 벤치마크 페이지로 이동
      </p>
      <Background className="absolute w-full h-128" />
    </Link>
  );
}

서비스 개발이 어느 정도 진행된 상태라 노가다로 바꾸기에는 조금 곤란했기에 AI 에이전트를 사용했다.

Cursor 에디터를 즐겨 사용하기 때문에 Cursor Agent 에서 모델은 claude-4-sonnet을 사용했다.

LLM 컨텍스트 윈도우 크기를 고려하여 페이지에 대해 각각 번역 작업을 요청하였다.

벤치마크 페이지 국제화 작업을 위해 메시지를 보낸 모습. 로딩 중...cursor-agent-claude-4-sonnet

따로 국제화에 필요한 번역 한-영 쌍을 만들지 않았기 때문에 LLM이 자율적으로 번역을 하도록 하였다.

타임라인 페이지 번역 결과.

웹 미리보기
로딩 중...

한국어로 작성된 포스팅 번역하기

Takeoff. 서비스는 해외 AI 커뮤니티에서 특정 이슈를 다루는 게시글을 찾아 정리하는 서비스이다.

Takeoff. 서비스 제작기 참고

AI를 통해 한국어로 게시글을 작성한 후 저장하기 떄문에 국제화를 위한 번역 작업이 필요하다.

번역 작업을 위해 구글 gemini-2.5-flash-lite-preview-06-17 모델을 사용했고, 게시글 특성상 번역하기 까다로운 기술 용어들이 많기 때문에 이를 고려하여 프롬프트를 작성하였다.

프롬프트에는 기술적인 용어를 최대한 유지하고, 마크다운이 훼손되지 않도록 하는 문구를 작성하였다.

typescript
export const TRANSLATION_CHAT_TEMPLATE = ChatPromptTemplate.fromMessages([
	[
		'system',
		`You are a professional AI content translator specializing in technical and AI-related content. Your task is to translate the given text accurately while maintaining:
 
1. Technical accuracy and terminology
2. Natural flow in the target language
3. Cultural appropriateness
4. Proper formatting and structure
 
## Guidelines:
- Preserve all technical terms and their meanings
- Maintain the original tone and style
- Keep proper nouns, brand names, and URLs unchanged
- Preserve markdown formatting if present
- Ensure the translation sounds natural to native speakers
- For AI/ML terms, use commonly accepted translations in the target language
- Translate the content exactly as written without adding any explanations, interpretations, or embellishments
- Do not insert flowery language, additional context, or editorial comments
- Keep the translation direct and faithful to the original meaning and style
 
## Language Codes:
- en: English
- ko: Korean (한국어)
 
## Output Format:
Please provide the translation in the following JSON format:
{{
  "translatedTitle": "translated title here",
  "translatedContent": "translated content here"
}}`,
	],
	[
		'human',
		`Please translate the following content to {language}:
 
Title: {title}
Content: {content}`,
	],
]);

Langchain을 사용하여 AI 모델과 JSON 파서를 연결하여 체인을 생성 후 JSON 파싱을 하도록 하였다.

typescript
// 번역 프롬프트 생성 (ChatPromptTemplate 사용)
const promptValue = await getTranslationPrompt(post.title, post.content, language);
 
// AI 모델과 JSON 파서를 연결한 체인 생성
const chain = TranslateService.translator.pipe(new JsonOutputParser<TranslationResult>());
 
// 번역 실행 및 JSON 파싱
const translationResult = (await chain.invoke(promptValue)) as TranslationResult;
 
// 번역 결과 검증
if (!translationResult.translatedTitle || !translationResult.translatedContent) {
    throw new Error('번역 결과가 완전하지 않습니다.');
}
 
return translationResult;

번역 결과 저장을 위한 데이터베이스 스키마를 작성하여 게시물을 참조하는 번역 결과를 저장할 수 있도록 한다. ORM은 drizzle-orm을 사용했다.

typescript
export const aiPostTranslations = sqliteTable('ai_post_translations', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  aiPostId: integer('ai_post_id').references(() => aiPosts.id),
  language: text('language').notNull(),
  title: text('title').notNull(),
  content: text('content').notNull(),
  createdAt: text('created_at').notNull().default(sql`CURRENT_TIMESTAMP`),
  updatedAt: text('updated_at').notNull().default(sql`CURRENT_TIMESTAMP`),
});

이제 기능을 묶어서 번역과 저장을 동시에 할 수 있도록 함수를 작성했다.

typescript
export class TranslateService {
    //...
    static async translateAndSaveAiPost(
		aiPostId: number,
		post: { title: string; content: string },
		language: Language,
		forceRetranslate = false
	): Promise<TranslationResult> {
		// 기존 번역 확인 (강제 재번역이 아닌 경우)
		if (!forceRetranslate) {
			const existingTranslation = await this.getExistingTranslation(aiPostId, language);
			if (existingTranslation) {
				return {
					translatedTitle: existingTranslation.title,
					translatedContent: existingTranslation.content,
				};
			}
		}
 
        console.log(`Translating post ${post.title}...`);
		// 새로운 번역 수행
		const translation = await this.translate(post, language);
        console.log(`Translated post ${translation.translatedTitle}...`);
 
		// 번역 결과 저장
		await this.saveAiPostTranslation(aiPostId, language, translation);
        console.log(`Saved translation for post ${post.title}...`);
 
		return translation;
	}
}

구현한 함수를 실제 서비스 코드에 적용했다. 이 작업은 게시글이 한국어로 작성된 후 진행되어야 하기 때문에 이를 고려하였다.

typescript
// ...
// 포스트 처리
const processedPost = await writer.processPost(result, similarPosts.map((post) => post.content));
logInfo(`Processed post: ${processedPost.title}`, SERVICE_TAG, OPERATION_TAG);
const savedPost = await postManager.savePost(processedPost);
if (savedPost) {
    //.....
    // 번역
    if (config.translate) {
        await TranslateService.translateAndSaveAiPost(savedPost.id, 
            { title: savedPost.title, content: savedPost.content }, 'en', true);
        logInfo(`Translated post`, SERVICE_TAG, OPERATION_TAG);
    }
    // ...
}
// ...

게시글이 저장된 후 값을 반환했을 때만 번역 작업을 진행하도록 하였다.

실제 서비스에서 번역 작업을 진행하는 모습. 로딩 중...translate-post

작업 결과를 비교해보면 다음과 같다.

Original
Translation
양자 AI 알고리즘의 혁신적 성능 입증 연구팀, 커널 기반 머신러닝에서 양자 속도 향상(Quantum Speedup) 성공적 시연 최첨단 고전 컴퓨터를 능가하는 성능 달성 핵심 기술 및 방법론 양자 광자 회로 및 맞춤형 머신러닝 알고리즘 활용 단 두 개의 광자만으로 기존 고전 컴퓨팅 방식 대비 속도, 정확성, 효율성 증대 얽힌 게이트(entangled gates) 불필요, 광자 주입(photon injection) 방식 채택 펨토초 레이저를 이용, 붕규산 유리 기판에 데이터 분류를 위한 정보 기록 6가지 고유한 구성으로 광자 주입 후 하이브리드 양자-이진 시스템으로 처리 실제 적용 및 잠재력 양자 머신러닝이 실제 문제에 적용된 최초 사례 중 하나 이진 컴퓨터로는 시뮬레이션 불가능한 이점 제공 단일 큐비트 양자 컴퓨팅 시스템에도 적용 가능 커널 기반 머신러닝 분야에서 데이터 정렬 등 다양한 응용 가능성 자연어 처리 및 기타 지도 학습 모델에서 더욱 효율적인 알고리즘 개발 기대 기술적 시사점 및 미래 전망 하이브리드 컴퓨터 시스템에서 양자 컴퓨터가 탁월한 성능을 발휘하는 작업을 식별하는 새로운 방법론 제시 기술의 확장성(Scalability) 입증: 광자 또는 큐비트 수 증가 시 성능 향상 가능 현재 모델의 전력 소비 한계를 넘어설 수 있는 머신러닝 시스템 개발 가능성 시사 광자 프로세서가 표준 머신러닝 성능을 향상시키는 하이브리드 방식의 문 개방
Demonstration of Innovative Performance of Quantum AI Algorithms Research team successfully demonstrates Quantum Speedup in kernel-based machine learning Achieved performance exceeding state-of-the-art classical computers Core Technologies and Methodologies Utilized quantum photonic circuits and custom machine learning algorithms Increased speed, accuracy, and efficiency compared to existing classical computing methods using only two photons Adopted photon injection method, eliminating the need for entangled gates Used femtosecond lasers to record information for data classification on borosilicate glass substrates Processed after photon injection into a hybrid quantum-binary system with six unique configurations Practical Applications and Potential One of the first instances of quantum machine learning applied to real-world problems Provides advantages impossible to simulate with binary computers Applicable to single-qubit quantum computing systems Potential for various applications such as data sorting in kernel-based machine learning Expectation of developing more efficient algorithms in natural language processing and other supervised learning models Technical Implications and Future Outlook Presents a new methodology for identifying tasks where quantum computers excel in hybrid computer systems Demonstrates the scalability of the technology: performance can be improved by increasing the number of photons or qubits Suggests the possibility of developing machine learning systems that can overcome the power consumption limitations of current models Opens the door for hybrid approaches where photonic processors enhance standard machine learning performance
Demonstration of Innovative Performance of Quantum AI Algorithms Research team successfully demonstrates Quantum Speedup in kernel-based machine learning Achieved performance exceeding state-of-the-art classical computers Core Technologies and Methodologies Utilized quantum photonic circuits and custom machine learning algorithms Increased speed, accuracy, and efficiency compared to existing classical computing methods using only two photons Adopted photon injection method, eliminating the need for entangled gates Used femtosecond lasers to record information for data classification on borosilicate glass substrates Processed after photon injection into a hybrid quantum-binary system with six unique configurations Practical Applications and Potential One of the first instances of quantum machine learning applied to real-world problems Provides advantages impossible to simulate with binary computers Applicable to single-qubit quantum computing systems Potential for various applications such as data sorting in kernel-based machine learning Expectation of developing more efficient algorithms in natural language processing and other supervised learning models Technical Implications and Future Outlook Presents a new methodology for identifying tasks where quantum computers excel in hybrid computer systems Demonstrates the scalability of the technology: performance can be improved by increasing the number of photons or qubits Suggests the possibility of developing machine learning systems that can overcome the power consumption limitations of current models Opens the door for hybrid approaches where photonic processors enhance standard machine learning performance
Original50%Translation