본문 바로가기

Coding, Testing, Challenge

토스 미니앱 공통 내비바가 안 뜰 때, 설정이 아니라 한 줄이 문제입니다

registerApp 한 줄 차이로 갈리는 내비게이션 바

설정을 다 맞췄는데 화면 위에 아무것도 안 뜰 때가 있습니다.

토스 미니앱의 공통 내비게이션 바가 그렇습니다. 저희는 이걸 찾는 데 아홉 번 틀렸습니다.

이번 포스팅에서는 원인 한 줄과, 그걸 확인하는 방법을 정리해 보도록 하겠습니다.

먼저 확인할 것

2026년 9월, 미니앱 50개에 같은 조치를 적용하며 확인한 내용입니다.

리액트 네이티브 미니앱 기준이고, 웹뷰 미니앱은 구조가 다릅니다.

그러면 결론부터 보겠습니다.

등록 함수를 무엇으로 쓰느냐가 전부입니다

// 내비바가 뜹니다
export default AppsInToss.registerApp(AppContainer, { context });

// 내비바가 안 뜹니다
export default Granite.registerApp(AppContainer, { context });

차이는 이 한 줄뿐입니다.

토스 공통 내비바는 플랫폼이 위에 덮어 주는 게 아니라 우리 번들 안에 들어 있는 리액트 컴포넌트이기 때문입니다.

그 컴포넌트를 마운트해 주는 건 AppsInToss.registerApp 뿐입니다.

granite.config.ts 의 navigationBar 설정은 그 컴포넌트가 읽는 값입니다. 컴포넌트가 없으면 설정이 아무리 정확해도 읽을 주체가 없습니다.

설정만 들여다보다 아홉 번을 틀렸습니다

증상이 "설정한 대로 안 나온다"였기 때문에 계속 설정 쪽만 봤습니다.

로고 주소, 이미지 인코딩, 다크 모드 아이콘, 네트워크 응답까지 전부 확인했습니다. 전부 정상이었습니다.

같은 원인으로 죽어 있던 것이 더 있었습니다. 더보기 버튼, 닫기 버튼, 안드로이드 뒤로 가기, 브랜드 색상이 한꺼번에 동작하지 않았습니다.

이것들이 전부 같은 컴포넌트가 그리는 것이라 같이 사라진 것입니다.

번들을 문자열로 검색하면 바로 판정됩니다

결정적인 증거는 빌드 산출물에서 나왔습니다.

내비바 컴포넌트가 들어갔다면 관련 문자열이 번들 안에 있어야 합니다.

grep -o "navBarImpression" dist/bundle.*.js | wc -l

고치기 전에는 0, 고친 뒤에는 20 이 나왔습니다.

여기서 얻은 교훈을 그대로 옮기면 이렇습니다. 증상이 "설정대로 안 나온다"일 때는, 그 설정을 읽는 코드가 번들에 있는지부터 확인합니다.

헤더를 켜면 빈 흰 줄이 겹칩니다

내비바가 뜨기 시작하면 다음 문제가 옵니다.

headerShown: true 로 두면 Granite 기본 헤더가 내비바 위에 한 겹 더 뜹니다. 비어 있는 흰 띠라 알아보기도 애매합니다.

여기에 앱 자체 헤더까지 있으면 뒤로 가기 버튼이 둘이 됩니다. 이건 검수에서 반려 사유가 됩니다.

헤더를 걷으면 여백도 같이 사라집니다

그래서 앱 헤더를 제거했더니 이번에는 콘텐츠가 내비바에 붙었습니다.

그 헤더가 상단 여백까지 같이 들고 있었기 때문입니다. 실측으로 0~8px 가 사라져 카드 윗변이 잘려 보였습니다.

조치는 루트 컨테이너에 여백을 되돌려 주는 것입니다.

const styles = StyleSheet.create({
  root: { flex: 1, paddingTop: space.md },
});

헤더를 지울 때는 그 헤더가 갖고 있던 여백도 같이 지워진다고 생각하시는 편이 안전합니다.

브랜드 로고는 사본을 서빙하면 안 됩니다

내비바가 떠도 로고 때문에 반려될 수 있습니다.

저희는 자체 서버에서 같은 이미지를 서빙했습니다. 픽셀이 완전히 같은데도 계속 반려됐습니다.

검수는 같은 그림인지가 아니라 어디서 오는지를 봅니다. 콘솔에 업로드해 받은 주소를 brand.icon 에 그대로 넣자 7분 만에 승인됐습니다.

덧붙이면 brand.icon 은 주소라서 번들에는 주소만 들어갑니다. 그림을 바꾸면 이미 배포된 앱도 새 그림을 씁니다. 이 경우엔 재빌드가 필요 없습니다.

다섯 줄로 줄이면

  1. 내비바는 AppsInToss.registerApp 으로만 뜹니다. Granite.registerApp 이면 설정이 맞아도 안 뜹니다.
  2. 더보기·닫기·뒤로 가기·브랜드 색이 한꺼번에 죽었다면 같은 원인입니다.
  3. 들어갔는지는 번들 문자열 검색으로 판정합니다.
  4. headerShown 을 켜면 빈 헤더가 겹치고, 헤더를 지우면 상단 여백이 함께 사라집니다.
  5. 브랜드 로고는 콘솔이 준 주소를 그대로 씁니다. 사본은 픽셀이 같아도 반려됩니다.

설정을 다시 보기 전에, 번들 안을 한 번 검색해 보시는 건 어떨까요?

그러면 오늘도 모두 스테이블 하세요.


만든 것들