PWA 스토어 개발기


1. PWA 스토어를 만들게 된 계기
PWA를 알게 된 건 작년 7월. 홈화면에서 바로 사용 가능하고 오프라인 캐싱에 푸시알림까지 지원을 한다기에 네이티브 기능이 필요 없는 서비스의 경우 생산성 빠르게 뽑을 수 있겠다라는 생각에 매력을 느꼈다. 심지어 핸드폰, 태블릿, 컴퓨터에도 설치가 된다니
그래서 오만하지만 **"너가 미래다"**라는 생각을 했다.
이름도 심지어 Progressive Web App
이다.
그런데 설치를 하려면 브라우저에서 공유 버튼을 누르고 "홈화면에 설치"까지 눌러야 해서 좀 번거롭네..? 싶어서 이를 해결하고자 했다.
우선 설치 과정을 통일화해버리면 좋겠다라는 생각이 들었다. 또 PWA라는 아이템 자체가 너무 좋아보였기에 PWA를 모으고 설치까지 할 수 있는 스토어를 구상하게 된다.
그렇게 바로 친한 개발자 동생한테 전화 후 신명나게 떠들고 기획에 착수하게 된다.
2. 이름은 Wepp Store로
PWA는 뭔가 입에 달라붙지 않을 것 같아서 Web + App = Wepp이라는 신조어를 만들었다.
그래서 프로젝트명은 Wepp Store가 됐다.
우선 사용자와 개발자 측면에서의 이점을 정리해보자면
사용자
- 모바일, 태블릿, 데스크탑 구분 없이 어떤 기기든 같은 서비스를 이용 가능
- 모든 서비스가 무료!
개발자
- 앱으로 만드는 번거로움 없이 웹으로 만들면 생산성이 훨씬 증가
- 복잡한 앱스토어 승인 필요 X, 앱스토어에 올리는 비용 감소
- Wepp Store가 잘된다면 서비스 홍보 효과
- 스토어에서 웹사이트 백링크를 걸기 때문에 조금이나마 SEO 향상 가능
이 정도가 되겠습니다.
BM은 Wepp 3개 이상 등록부터 유료로 생각했지만 이건 사용자부터 모으고 하기로 하고 일단 만들기로 했다.
3. 개발 기획 시작
문제는 PWA는 해당 서비스 웹브라우저에서 설치 가능하기 때문에 스토어에서 바로 직접 설치는 불가능했다. 직접 설치로 하고 싶어 iframe에도 넣어보고 해봤지만.. 정책상 다 안 됐다..
그래서 그냥 설치 버튼을 누르면 서비스로 이동시키고 사용자보고 알아서 설치하라는 생각도 해봤지만 설치 버튼으로 꼭 설치하게 하고 싶었다.
"기술적 한계로 못 만들게 되는 건가"라는 좌절감이 올 때쯤
문득 군대에서 Vanilla.js로 사이트를 만들었던 기억이 나면서
url hash로 모달을 띄우는 방법이 떠올랐다.
개발자가 서비스에 설치 모달을 심고 특정 hash로 이동시켰을 때 설치 UI가 뜨면 성공.
이 방법도 설치버튼 -> 설치버튼
이지만
설치버튼 -> 주소창에 공유 버튼 -> 홈화면에 추가
이 방법보다 클릭도 줄고, 버튼 찾고 찾고 하는 것보다 사용자 입장에서 훨씬 편해지게 되므로
다음 문제인 어떻게 개발자가 서비스에 설치 모달을 심게 할 수 있을 지 고민을 했다.
(1) 라이브러리로 만들까?
- 그러면 프레임워크별로 다 만들어야 하나..?
(2) 그냥 js로 할까?
- React의 경우 React Dom에 포함을 못 시키는데..?
- 생각해보니 굳이 가상돔에 포함이 돼야 하나?
- 그러고보니 js로 하면 script 태그를 이용해서 사이트(도메인) 인증도 가능하네?
바로 단일 js 파일을 만들어보기로 했다.
4. 설치 모달 테스트
설치 모달을 띄울 hash는 #wepps-install-modal
으로 하고 스크립트를 만들어봤다.
favicon에서 로고, title 태그에서 Wepp 이름을 가져오고
javascriptconst initializePWAInfo = () => { const nameElement = document.getElementById('wepp-name'); const logoElement = document.getElementById('wepp-logo'); const name = document.title; const logo = getFaviconHref(); nameElement.textContent = name; logoElement.src = logo;}
모달 이벤트 함수를 만들고
javascriptfunction handleModalClose() { window.location.hash = ''; const modal = document.getElementById('wepp-install-modal'); modal.style.display = 'none';} function preventModalContentClick(event) { event.stopPropagation();} function initializeModalEvents() { const modal = document.getElementById('wepp-install-modal'); const skipButton = document.getElementById('wepp-skip-button'); const modalContent = modal.querySelector('.wepp-modal-content'); // Close Modal on Background Click modal.addEventListener('click', handleModalClose); modalContent.addEventListener('click', preventModalContentClick); skipButton.addEventListener('click', handleModalClose);}
window hashchange 이벤트에 등록해주면?

정말 기뻤습니다.
5. IOS 대응하기
그러나 IOS 사파리는 버튼으로 PWA를 설치하기 위한 beforeinstallprompt를 지원하지 않아서 설치 버튼을 띄우는 것이 불가능했다.. 아무리 찾아봐도.. 언제 지원해줄 건지.. 말도 없이.......
그래서 어쩔 수 없이 IOS는 따로 대응해주기로 합니다.

6. 스토어 개발
일단 기술적으로 구현이 가능한 것을 알았으니 개발 스택을 정할 차례입니다. 아무래도 스토어이고 사람들이 검색을 통해서도 찾아야 하기 때문에 FE는 Nextjs로 확정. 백엔드를 뭘로 할 지 참 고민을 많이 했다.
(1) next에서 다 처리를 할까?
- 코드가 너무 커질 것 같은데..
(2) 어드민 템플릿을 쉽게 쓸 수 있는 Django를 쓸까?
- js랑 파이썬 둘 다 쓰면 헷갈리지 않을까?
이러한 이유로 Nestjs를 선택했다.
7. 완성
어찌저찌 완성을 했다.

열심히도 했다
8. 회고
콩깎지가 꼈었는지 처음에 기획할 때는 이걸 안 쓸 이유가 없다라고 생각했는데 생각해보니 사용자 입장에서는 이걸 굳이 쓸 이유가 없었다.
미련이 많이 남아 시간이 걸려도 어떻게든 조금씩 사용자를 모아볼 계획이다.
https://weppstore.com깃허브
https://github.com/wepp-store/weppstore-fe