푸터에 다국어 법적 공시 링크 추가
목차
최근 서비스의 푸터 컴포넌트에 쿠키 정책, 개인정보 정책 같은 법적 공시 링크를 다국어(4개 로케일)로 추가했다. 작업 자체는 간단해 보이지만, 이 안에는 글로벌 서비스의 법적 규정 대응, 다국어 시스템 설계, 그리고 사용자 신뢰 구축이라는 여러 층이 얽혀 있다.
왜 푸터인가
푸터는 보통 서비스의 가장 아래쪽에 위치한 조용한 공간이다. 하지만 그렇기 때문에 중요하다. 법적 의무가 있는 링크들—쿠키 정책, 개인정보 보호 정책, 이용약관—을 사용자가 "찾기 위해 노력할 필요 없이" 항상 접근 가능한 장소에 배치하는 게 웹 표준이자 법적 기준이다. 법적 공시를 숨기려고 한다면 오히려 규제 위험을 키우는 셈이다. 한국에서 개인정보보호법, 해외에서는 GDPR나 CCPA 같은 규정들이 모두 사용자가 쉽게 접근 가능한 정책 공시를 요구한다. 그래서 푸터는 "필수 고정 배치 영역"이 되었다.
문제는 우리 서비스가 단일 지역에만 사용되지 않는다는 것이다. 각 지역의 정책 페이지가 다르고, 무엇보다 사용자가 보는 언어 자체가 다르다. 영어 사용자에게 한국어 링크 텍스트를 노출할 수는 없다. 그래서 단순히 "링크를 추가한다"가 아니라 "각 로케일마다 올바른 언어의 링크를, 올바른 정책 페이지로 연결한다"는 복잡도가 생긴다.
기술적 구현 구조
변경 파일을 보면 src/components/Footer.astro와 src/lib/i18n.ts 두 개가 주인공이다.
Footer.astro는 UI 렌더링 담당이다. 푸터 레이아웃을 정의하고, 법적 링크 섹션을 배치하는 역할이다. 여기서 중요한 건 하드코딩하지 않는다는 것이다. "쿠키 정책" 같은 텍스트를 컴포넌트 안에 직접 문자열로 박으면, 각 언어별로 같은 코드를 여러 번 작성해야 한다. 유지보수도 악몽이 된다.
그래서 i18n 라이브러리가 들어간다. src/lib/i18n.ts는 현재 사용자의 로케일을 파악하고, 그에 맞는 문자열 번역을 제공하는 역할이다. Footer에서는 단순히 i18n 함수를 호출해서 "cookies_policy_label", "privacy_policy_label" 같은 키를 던지고, i18n이 현재 로케일에 맞게 "Cookies Policy", "쿠키 정책", "Política de Cookies" 같은 실제 문자열을 반환한다.
이 분리가 중요한 이유는 횡단 관심사 분리이기 때문이다. 푸터는 "뭘 어디에 배치할지"에만 집중하고, i18n은 "어떤 언어로 뭐라고 표시할지"에 집중한다. 나중에 언어를 추가하거나 정책 텍스트를 수정할 때, 푸터 컴포넌트에는 손도 안 댄다.
4개 로케일 선택의 배경
커밋 메시지에 "i18n 4-locale"이라고 명시된 것으로 보아, 현재 서비스에서 4개의 언어 또는 지역을 지원하고 있다는 뜻이다. 이게 구체적으로 어느 4개인지는 비즈니스 전략에 따른 것일 텐데, 일반적으로 이런 선택을 할 때는:
- 시장 규모: 얼마나 많은 사용자가 그 언어를 사용하는가
- 규제 복잡도: 그 지역의 법적 요구사항은 얼마나 까다로운가
- 운영 비용: 각 언어별 번역, 정책 페이지 관리 비용
- 확장 가능성: 현재는 4개지만, 나중에 추가될 가능성
팀장 입장에서는 이 선택이 기술적으로만 타당해야 하는 게 아니라, 비즈니스 팀과의 협의가 반영되어야 한다. "왜 정확히 4개인가"라는 질문에 대답할 수 있어야 한다. 만약 앞으로 5번째 언어가 필요해진다면, 이 i18n 시스템이 유연하게 확장되어야 한다. 그래서 i18n 라이브러리를 설계할 때는 "하드코딩된 4개"가 아니라 "설정 가능한 N개"로 만들어두는 게 일반적이다.
링크 경로 관리의 함정
한 가지 더 생각해야 할 부분이 있다. 법적 공시 링크가 각 로케일마다 다를 수 있다는 점이다. 예를 들어:
- 한국 사용자의 개인정보 정책: /ko/privacy
- 미국 사용자의 개인정보 정책: /en/privacy (또는 별도의 CCPA 전용 페이지)
- 유럽 사용자의 개인정보 정책: /eu/privacy (GDPR 대응)
정책 콘텐츠 자체도 다를 수 있고, 물리적 페이지 경로도 다를 수 있다. i18n.ts에서는 단순히 문자열 번역만 하는 게 아니라, 링크 경로도 로케일에 맞게 매핑해야 한다. Footer에서는 i18n에서 받은 URL을 신뢰하고 그냥 href에 박으면 된다.
이런 설계를 제대로 하지 않으면, Footer 렌더링 로직이 복잡해진다. "현재 로케일이 뭐니까, 그에 맞게 다른 경로를 사용해야지"라는 로직이 푸터 컴포넌트 안에 들어오게 되는데, 그건 정확히 해서는 안 될 일이다.
팀 관점: 우선순위와 협업
개발팀 입장에서, 이 작업은 "버그 수정"도 아니고 "새로운 기능"도 아니라 "규정 대응"이다. 이런 작업은 기한이 있다. 각 지역의 개인정보보호법 개정이 되거나, 새로운 시장에 진입하거나, 감시 기관의 공식 공지가 내려오면 미룰 수 없다. 그래서 우선순위 결정이 중요하다.
백로그에 수없이 많은 "개선" 요청이 있겠지만, "법적 규정 미충족"은 기술 부채가 아니라 법적 위험이다. 그래서 이 작업이 스프린트에 들어온 것 같다. 개발팀 입장에서는 "큰 기능도 아닌데 왜?"라고 생각할 수 있지만, 제품/법무팀 입장에서는 "반드시 해야 할" 작업이다.
협업 측면에서도 배울 점이 있다. 이런 작업을 할 때는:
1. 요구사항 명확화: 정확히 어느 정책 페이지를 링크해야 하는가? 각 로케일별로 어느 페이지인가?
2. 테스트 전략: 각 로케일을 실제로 전환해서 링크를 확인했는가? 잘못된 정책 페이지로 링크되는 건 아닌가?
3. 문서화: i18n 라이브러리에 새로운 키를 추가할 때, 향후 담당자가 어떻게 유지보수할지 가이드가 필요하다.
회고: 작은 변경이 가진 의미
푸터에 링크 몇 개 추가하는 것처럼 보이지만, 이건 다국어 시스템의 일관성을 유지하는 작업이기도 하다. 특히 i18n이 이미 도입된 프로젝트라면, 새로운 다국어 콘텐츠를 추가할 때마다 같은 패턴을 따르게 된다. 따라서 이 작업을 제대로 하면, 향후 다른 컴포넌트에서도 같은 방식으로 다국어를 지원할 수 있는 선례가 된다.
반대로, 만약 이 작업이 기술적으로 제대로 되지 않는다면? 예를 들어 Footer에 하드코딩된 링크와 i18n을 섞어 쓴다면, 나중에 정책이 변경될 때 여러 곳을 수정해야 한다. 혼란도 생기고, 버그도 생긴다. 그래서 "작은 작업"이라도 "올바른 방식"으로 하는 게 팀의 생산성과 신뢰성을 지킨다.
마지막으로, 글로벌 서비스의 책임이란 이런 디테일에 있다는 걸 다시 한 번 느낀다. 사용자가 자신의 언어로 정책을 읽을 수 있고, 올바른 링크로 접근할 수 있게 하는 것. 그게 작은 배려처럼 보이지만, 규정 준수의 기초이고, 사용자 신뢰의 한 부분이다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.