개발 slecs

메타 태그 언어 누수 제거, 다중사이트 i18n 잘못된 가정을 고치며

목차

다중 사이트를 운영할 때, 각 사이트별 기본 언어와 지역화 전략이 다르면 언뜻 작아 보이는 메타 태그 하나도 예상 밖의 곳에서 터진다. 이번 작업은 그런 "누수"를 잡는 일이었다.

배경: 다국어 환경에서 문제를 안고 있는 줄 몰랐던 일

우리는 여러 사이트를 동시에 운영 중이다. 각 사이트마다 기본 서빙 언어, 사용자층, SEO 전략이 다르다. 네비게이션 라벨이나 메타 태그(페이지 제목, description, og:title 등)는 그 사이트 방문자가 보는 첫인상이다. SEO 검색 결과에도 나타나고, SNS 공유 카드에도 표시된다. 때문에 사이트별 언어/지역화 규칙을 정확히 지키는 것이 중요하다.

문제는 src/app/[site]/[...path]/page.tsx 같은 동적 라우팅 환경에서 더 자주 터진다. 한 컴포넌트가 여러 사이트·여러 경로를 담당할 때, 각 상황에 맞는 언어 컨텍스트를 정확히 전파하지 못하면, 특정 사이트(예: dex)에서만 설정한 한국어 라벨이 다른 사이트에서도 노출되는 식의 "누수"가 생긴다.

왜 이런 일이 생기는가

일반적으로 이런 버그는 몇 가지 패턴에서 비롯된다:

  • 언어 설정의 상태 관리 중복: 라우트 params에서 한 번, context에서 한 번, 컴포넌트 상태에서 또 한 번 관리되면서 중간에 동기화 빠짐
  • 기본값 설정의 과신: "모든 사이트가 영어부터 시작한다"는 가정을 코드에 하드코딩했는데, 특정 사이트는 한국어가 기본값이라서 그 값이 누수됨
  • 동적 라우팅에서 컨텍스트 전파 누락: [site][...path] 파라미터에서 사이트 정보를 읽지만, 그걸 네비/메타 라벨 생성 함수까지 제대로 넘기지 않음
  • 테스트 커버리지의 한계: 로컬 개발은 한 사이트 기준으로만 테스트하고, 여러 사이트를 동시에 서빙하는 프로덕션 환경을 제대로 검증하지 않음

해결한 방식

네비게이션과 메타 라벨을 생성하는 로직을 사이트/경로별로 명확히 격리했다. 즉:

  1. 라우트 params에서 site 를 읽는 시점에, 그에 맞는 언어 기본값을 설정
  2. 네비 라벨과 메타 태그를 생성하는 함수에 항상 site 를 명시적으로 전달
  3. 각 사이트별로 허용하는 언어 리스트를 별도로 관리하고, 그것만 사용하도록 화이트리스트 방식 적용

예를 들어, 다음과 같은 방식에서:

// ❌ 이전: 암묵적 가정
const navLabel = getNavLabel(pathname);  // 현재 사이트가 뭔지 알 수 없음
const metaTitle = siteConfig.title;      // 기본값이 뭔지 불명확

// ✅ 개선: 명시적 전달
const navLabel = getNavLabel(pathname, { site, locale });
const metaTitle = getSiteMetaTitle(site, locale, pathname);

팀과 회고

이번 수정을 통해 얻은 배움:

  • 초기 설계 단계에서 "다국어 환경의 경계"를 명확히 그어야 한다. "언어를 지원한다"는 말이 추상적인데, 각 사이트/경로에서 정확히 "어느 언어를 주 언어로 하고, 어느 언어까지만 선택 가능한가"를 문서화하고 코드에도 명시적으로 표현해야 한다.

  • 동적 라우팅 환경에서는 컨텍스트를 "한 번만" 읽고 끝내지 말 것. 라우트 params → state → 함수 호출 과정에서 "현재 사이트가 무엇인가"라는 정보를 계속 의식하고 전달해야 한다. 중간에 빠지면 기본값이 악의 없이 작동한다.

  • 프로덕션 환경을 대표하는 테스트/모니터링이 없으면 이런 버그는 잡기 어렵다. 로컬에서는 한 사이트만 서빙하고, CI에서도 "한국어 + 기본 경로"만 테스트하면 넘어간다. 여러 사이트, 여러 언어 조합을 실제로 렌더링해보고 메타 태그를 검사하는 과정이 필요하다.

결국 이런 누수는 "코드 리뷰에서 놓친" 것이 아니라, "시스템의 복잡성을 과소평가한" 데서 비롯됐다. 사이트 수와 언어 수가 곱해질수록 엣지 케이스는 기하급수적으로 늘어난다. 설계 단계에서 그 복잡성을 정직하게 인정하고, 코드와 테스트에도 반영해야 한다는 걸 다시 한 번 확인했다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.