Next.js App Router에서 메타데이터를 하드코딩하지 않고 next-intl 라이브러리를 활용해 SEO에 최적화된 다국어 웹사이트를 구축하는 방법을 알아봅니다.
다국어 웹사이트를 운영할 때 가장 흔히 저지르는 실수가 있습니다. 바로 메타데이터를 영어로만 하드코딩하는 것입니다. 오늘은 이 문제를 next-intl 라이브러리로 어떻게 깔끔하게 해결할 수 있는지 공유합니다.
문제 상황: 영어로 고정된 메타데이터
hafuture는 한국어, 영어, 일본어를 지원하는 글로벌 서비스입니다. 그런데 어느 날 Google Search Console을 확인하던 중 이상한 점을 발견했습니다. 한국어 페이지(/ko)에 접속해도 HTML의 <title>과 <meta description>이 영어로 표시되고 있었던 것입니다.
<!-- /ko 페이지인데 영어? -->
<title>Free Online Tools for Text, PDF & Images | Hafuture</title>
<meta name="description" content="Fast, private, browser-based tools..." />
이는 분명히 SEO에 악영향을 미치며, 한국어 검색 결과에서 불이익을 받을 수 있습니다.
원인: generateMetadata에서 하드코딩
문제의 원인은 layout.tsx의 generateMetadata 함수에 있었습니다:
// ❌ 잘못된 방식: 하드코딩
export async function generateMetadata(): Promise<Metadata> {
return {
title: {
default: "Free Online Tools for Text, PDF & Images | Hafuture",
template: "%s | Hafuture",
},
description: "Fast, private, browser-based tools...",
};
}
아무리 next-intl을 사용하고 있어도, 메타데이터 부분에서 번역 함수를 호출하지 않으면 정적인 영어 텍스트가 그대로 출력됩니다.
해결책: getTranslations 사용
next-intl은 서버 컴포넌트에서 사용할 수 있는 getTranslations 함수를 제공합니다. 이를 활용하면 generateMetadata에서도 동적으로 번역된 메타데이터를 생성할 수 있습니다.
1단계: 메시지 파일에 Metadata 섹션 추가
// messages/ko.json
{
"Metadata": {
"title": "텍스트, PDF, 이미지를 위한 무료 온라인 도구 | Hafuture",
"description": "빠르고 안전한 브라우저 기반 도구입니다...",
"ogTitle": "텍스트, PDF, 이미지를 위한 무료 온라인 도구 | Hafuture"
}
}
2단계: generateMetadata에서 getTranslations 호출
// ✅ 올바른 방식: next-intl 사용
import { getTranslations } from "next-intl/server";
export async function generateMetadata(
{ params }: { params: Promise<{ locale: string }> }
): Promise<Metadata> {
const { locale } = await params;
const t = await getTranslations({ locale, namespace: "Metadata" });
return {
title: {
default: t("title"),
template: t("titleTemplate"),
},
description: t("description"),
openGraph: {
title: t("ogTitle"),
description: t("ogDescription"),
},
};
}
하드코딩 vs next-intl 비교
| 비교 항목 | 하드코딩 (Custom) | next-intl 라이브러리 |
|---|---|---|
| 최종 HTML 결과 | 구현 실력에 따라 다름 | 완벽한 결과 보장 |
| 구현 난이도 | 높음 (서버/클라이언트 동기화 필요) | 낮음 (Next.js 전용 설계) |
| 실수 가능성 | 높음 (메타데이터 누락 등) | 낮음 (정해진 패턴) |
| SEO 영향 | 불안정 | 안정적으로 높은 점수 |
| 유지보수 | 어려움 | 쉬움 (JSON 파일만 수정) |
결과 확인
수정 후 각 언어별 페이지의 HTML을 확인해보면:
한국어 (/ko):
<title>텍스트, PDF, 이미지를 위한 무료 온라인 도구 | Hafuture</title>
<meta property="og:locale" content="ko_KR" />
일본어 (/ja):
<title>テキスト、PDF、画像のための無料オンラインツール | Hafuture</title>
<meta property="og:locale" content="ja_JP" />
이제 검색 엔진이 각 언어에 맞는 메타데이터를 정확히 인식할 수 있습니다!
관련 도구 써보기
다국어 지원으로 더욱 똑똑해진 Hafuture의 도구들을 만나보세요:
결론
Next.js App Router를 사용하고 있다면, SEO 실수를 방지하고 유지보수를 편하게 하기 위해 next-intl 도입을 강력하게 추천합니다. 특히 generateMetadata에서 getTranslations를 사용하면 "제목/설명 번역 안 됨" 문제를 가장 깔끔하게 해결할 수 있습니다.
다국어 지원은 단순히 텍스트를 바꾸는 것이 아닙니다. 사용자의 언어와 문화를 존중하는 첫걸음이니까요!
감사합니다. 🌏