
브라우저 히스토리와 하드웨어 백키의 극적인 타협점을 찾아서
웹의 히스토리 기반 뒤로가기와 웹뷰의 하드웨어 백키는 동작 원리가 근본적으로 다릅니다. 이 아티클은 두 환경의 고유 방식을 억지로 통합하지 않고, 공통 콜백으로 수렴시키는 추상화 구조를 설계하여 뒤로가기 문제를 깔끔하게 해결한 여정을 공유합니다. 덕분에 개발자들은 웹인지 앱인지 의식하지 않고 직관적인 컴포넌트 선언만으로 완벽한 네비게이션을 구현하게 되었습니다.
웹과 웹뷰를 동시에 지원하는 하이브리드 앱 환경의 프론트엔드 엔지니어에게 적극 추천합니다. 특히 모달, 바텀시트 등의 복잡한 네비게이션 스택 처리에 골머리를 앓고 있다면 아티클의 이원화된 콜백 매핑 아키텍처가 실무적인 돌파구가 될 것입니다.
웹 브라우저의 히스토리 방식과 안드로이드 하드웨어 백키 방식이 서로 달라, 하나의 프론트엔드 코드베이스에서 두 환경의 뒤로가기 동작을 일관되게 제어하기 어려웠습니다. 특히 단순 라우터 백을 실행하면 화면 전체가 뒤로 이동하여 떠 있는 모달이나 다이얼로그만 순차적으로 닫지 못하는 문제가 발생했습니다.
웹과 웹뷰 환경의 메커니즘을 억지로 하나로 합치지 않고, 동일한 콜백에 도달하도록 추상화했습니다. 웹뷰에서는 마운트 순서대로 data-order를 가진 보이지 않는 버튼을 렌더링하여 전역 백키 핸들러가 가장 최근의 버튼을 클릭하게 했고, 웹에서는 단일 싱글톤 매니저가 URL 해시(#modal)와 popstate 리스너를 소유하여 모달의 등록 및 히스토리 이벤트를 조율하도록 구현했습니다.
서비스 레이어의 개발 코드는 백키 처리 로직을 완전히 배제하고 오직 onHide와 onNativeBack 속성만 정의하도록 완전히 추상화되었습니다. 이를 통해 웹과 웹뷰 양쪽 환경 모두에서 복잡한 뒤로가기 분기문 없이도 안전하고 자연스러운 사용자 경험을 제공할 수 있게 되었습니다.
Trade-off
웹 환경에서 겹쳐 있는 모달들이 뒤로가기 한 번에 모두 닫히는 한계가 존재합니다. 또한 뒤로가기를 흡수하는 로직의 오작동을 방지하기 위해 100ms 타임아웃 같은 경험적 수치에 의존하는 트릭이나 화면 딤드 영역을 2배로 넓게 그리는 임시방편적 트릭을 일부 사용했습니다.
네이티브 앱의 물리적인 백키 동작 처리를 앱 내부에서 처리하지 않고, 브릿지를 통해 웹뷰(Javascript) 영역으로 위임하여 웹 애플리케이션이 직접 뒤로가기 동작을 제어하도록 하는 방식입니다.
웹뷰 환경에서 전역 백키 이벤트가 전달되었을 때, React 상태 밖의 DOM 마운트 순서를 활용하여 가장 위에 떠 있는 모달을 판별하고 물리적인 클릭 이벤트를 시뮬레이션하는 화면에 보이지 않는 컴포넌트입니다.
브라우저의 URL 해시(#modal) 및 popstate 리스너의 소유권을 컴포넌트 개별이 아닌 단일 객체로 집중화하여, 여러 모달 간의 히스토리 동기화 어긋남(Desync)을 방지하는 디자인 패턴입니다.









