Return

Support I18n with SEO Improvement

INFRASTRUCTURE

Situation

방문할 사용자들이 한 가지 언어로만 볼 수 있게끔 언어 설정을 도입할 필요성을 느낌.

Task

  • next-intl 를 활용 가능한 수준까지 확장하여 설정
  • next-intl 의 메세지 시스템을 본격적으로 적용
  • locale 을 적용한 메타데이터를 제공 및 SEO 최적화 진행
  • 언어 지원 설정을 포함한 sitemap 생성
  • 데이터베이스의 문자 컨텐츠에 대한 translation layer 추가
  • db 패키지와 어플리케이션 캐시 레이어 업데이트

Action

1. Configuration

  • next-intl 의 i18n configuration 을 prefix-url 형태로 지원하도록 구체화 (navigation, request, routing)
  • 어플리케이션의 모든 페이지를 [locale] 디렉토리 하위로 이동
  • locale prefix 에 대해 static parameter 를 생성하도록 설정
  • proxy.ts 에서 static asset 들은 i18n 의 영향을 받지 않도록 제외

2. Message System

  • CSR 페이지/컴포넌트 들은 useTranslations, SSR 페이지/컴포넌트 들은 getTranslations 를 사용하도록 설정
  • 흩어져 있던 formatting 설정을 request 안에 통합하고, useFormatter/getFormatter 를 사용하도록 일괄 설정

3. Metadata i18n

  • 데이터베이스를 거치지 않는 statc 페이지들의 메타데이터를 메시지 JSON 파일에 통합
  • 데이터베이스에 접근하는 페이지들은 query 를 분리하여 localize 된 메타데이터를 생성하도록 수정
  • 구현 중에 중복되는 로직을 발견하여 utils/server/metadata.tsserver-only 선언을 추가하여 별도 구성
  • canonical URLx-default 지원으로 Localize 된 메타데이터의 SEO best practices 적용

4. Sitemap Generation

  • 기존에 사용하던 next-sitemap 는 데이터베이스에 따라 생성되는 동적 route 를 수동으로 갱신해야 하고, CI 파이프라인에서도 post-build 스크립트를 사용해 추가적인 작업이 필요했음
  • 해당 라이브러리 대신 Next.js 에서 기본으로 지원하는 sitemap.ts 파일로 i18n 이 적용된 sitemap 생성
  • 이제 sitemap 은 /sitemap.xml 경로로 요청이 들어왔을 때 동적으로 생성됨

5. Translation Layer in Database

  • locale enum(ko, en) 추가
  • Localize 된 컨텐츠를 갖는 번역 관계 테이블 설계
  • 데이터베이스와 prisma 스키마 업데이트
  • title 컬럼은 타이포그래피 일관성 유지를 위해 제외 (Latin only)

6. Update Package and Cache layer

  • 변경된 스키마에 맞도록 prisma 의 query 수정
  • 캐시 레이어와 db 패키지 모두 기본 언어 설정 추가: 패키지에는 constants.ts 파일에 DEFAULT_LOCALE, 캐시 레이어는 routing.defaultLocale. 추후, db 패키지는 환경변수를 통해 기본 언어 설정을 할 수 있도록 변경할 수도 있음
  • posts-locale와 같이 locale 을 붙인 캐시 태그를 설정하여 보다 세밀한 캐시 관리

Result

이제 어플리케이션은 적절한 SEO 와 함께 한국어와 영어 모두 지원함. 지원 언어를 추가할 경우, locale enum 과 번역 테이블 추가로 가능.

한 가지, prefix locale 을 사용함으로써 언어 변경 시에 사이트의 모든 컴포넌트가 새로 그려지는 성능 저하 발견됨.