콘텐츠 요청 위젯이 사용자 언어 설정을 무시하던 버그 수정
목차
콘텐츠 요청(Content Request) 위젯이 사용자의 로케일 설정을 반영하지 못하고 있었다. 한국어/영어/중국어/일본어 중 어떤 언어로 설정했든 위젯의 텍스트와 UI가 그 언어로 표시되지 않고 있었던 거다. 이번 작업에서는 Base 레이아웃으로부터 로케일 정보를 제대로 전파해서 ContentRequestWidget 컴포넌트가 그걸 활용하도록 고쳤다.
왜 이런 버그가 생겼나
다국어를 지원하는 애플리케이션에서는 단순히 여러 언어 문자열을 준비하는 것만으로 부족하다. 각 컴포넌트가 "현재 사용자의 로케일이 뭔지" 알아야 그에 맞는 문자열과 포매팅을 적용할 수 있다. 특히 레이아웃(Base.astro)이 앱 전체의 로케일을 관리하는 상황에서, 하위 컴포넌트들이 그 정보를 받지 못하면 각자 기본값이나 잘못된 로케일로 렌더링되는 문제가 생긴다.
이 경우는 아마도 다음 중 하나였을 것 같다:
ContentRequestWidget이 독립적으로 개발됐을 때 아직 다국어 지원이 고려되지 않음Base레이아웃에서 로케일을 관리하지만, props로 명시적으로 하위 컴포넌트에 전달하지 않았음- 위젯의 텍스트가 하드코딩되어 있거나, 로케일 없이 기본값만 사용하고 있었음
실제 프로덕션에서는 이런 부분 버그(partial localization)가 자주 발생한다. 특히 나중에 추가되거나 재사용되는 컴포넌트들이 기존 로케일 체계와 연결되지 않을 때 그렇다.
어떻게 고쳤나
| 변경 전 | 변경 후 |
|---|---|
ContentRequestWidget이 독립 실행 |
Base.astro로부터 locale prop 수신 |
| 고정 언어(기본값) 렌더링 | 사용자 로케일에 맞춰 동적 렌더링 |
| i18n 키 참조 없음 | 로케일별 텍스트 맵 또는 i18n 함수 활용 |
코드 구조는 대략 이런 패턴이 됐을 거다:
<!-- Base.astro -->
<ContentRequestWidget locale={locale} />
<!-- ContentRequestWidget.astro -->
---
interface Props {
locale: string;
}
const { locale } = Astro.props;
const i18n = getTranslation(locale);
---
<div class="widget">
<h3>{i18n.title}</h3>
<input placeholder={i18n.placeholder} />
<button>{i18n.submit}</button>
</div>
이렇게 하면 사용자가 설정한 언어(ko / en / zh / ja)가 위젯 전체에 일관되게 적용된다.
배운 점과 다음 체크사항
다국어 앱에서 컴포넌트 개발할 때 주의할 점들:
- 레이아웃과 컴포넌트 간 props 전파 계획 — 로케일을 어디서 관리할 건지, 어떤 경로로 전파할 건지 먼저 정하기
- 공통 i18n 유틸 — 각 컴포넌트가 각자 번역 로직을 만들지 말고, 중앙화된
getTranslation()같은 함수 만들기 - props 문서화 — 컴포넌트 인터페이스에 "이 컴포넌트는
localeprop을 필요로 함"이라고 명시 - 테스트 커버 — 각 언어로 실제 렌더링됐는지 최소한 한 번은 브라우저/스크린샷으로 확인
- 레이아웃의 책임성 —
Base.astro같은 최상위 레이아웃이 모든 하위 컴포넌트에 필요한 메타 정보(로케일, 테마, 권한 등)를 전파하는지 체크
이 작업을 하면서 깨달은 건, 다국어 지원이라는 게 단순히 "문자열 파일을 여러 개 만드는" 것의 영역을 훨씬 넘는다는 것. 아키텍처 레벨에서 로케일을 어떻게 흘릴 것인지, 컴포넌트 간 어떤 계약(contract)을 유지할 것인지가 훨씬 중요하다. 한 개 컴포넌트가 로케일을 무시하면, 사용자는 언어를 선택했는데도 UI의 일부만 현지화된 어색한 경험을 하게 된다.
향후 새로운 위젯이나 폼 컴포넌트를 만들 때는 처음부터 "이게 locale prop을 받을 건가?"를 묻고, "그렇다면 어떤 텍스트들이 로케일 의존적인가?"를 정리한 후 시작하는 게 좋겠다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.