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.ts에server-only선언을 추가하여 별도 구성 canonical URL및x-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
localeenum(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 을 사용함으로써 언어 변경 시에 사이트의 모든 컴포넌트가 새로 그려지는 성능 저하 발견됨.