hafuture
Back to Blog

하드코딩 vs next-intl: Next.js에서 다국어 SEO를 완벽하게 구현하는 방법

Next.js App Router에서 메타데이터를 하드코딩하지 않고 next-intl 라이브러리를 활용해 SEO에 최적화된 다국어 웹사이트를 구축하는 방법을 알아봅니다.

Next.jsi18nnext-intlSEOTechnical

다국어 웹사이트를 운영할 때 가장 흔히 저지르는 실수가 있습니다. 바로 메타데이터를 영어로만 하드코딩하는 것입니다. 오늘은 이 문제를 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.tsxgenerateMetadata 함수에 있었습니다:

// ❌ 잘못된 방식: 하드코딩
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를 사용하면 "제목/설명 번역 안 됨" 문제를 가장 깔끔하게 해결할 수 있습니다.

다국어 지원은 단순히 텍스트를 바꾸는 것이 아닙니다. 사용자의 언어와 문화를 존중하는 첫걸음이니까요!

감사합니다. 🌏