Next.js 무한 스크롤 이슈에 Route as Modal 접목시키기

Sh031224
원티드랩 기술 블로그
6 min readOct 12, 2021

안녕하세요 원티드랩 프론트엔드팀 차승호입니다.

원티드 웹에서 Route as Modal을 적용하게된 이유를 무한스크롤과 함께 풀어나가도록 하겠습니다!

배경

무한스크롤 페이지에서 상세페이지로 이동한 이후 뒤로가기를 했을 때 이전 스크롤 위치와 다른 현상이 저희 원티드 웹에서 발생하였습니다.

이 자료를 살펴보면, 뒤로가기 기대치를 충족시키지 못하는 4가지 패턴을 소개하는데, 그 중 네 번째가
”제품 페이지에서 제품 목록 페이지로 탐색” 입니다.

왜 문제가 될까

사용자가 제품 목록의 맨 위로 돌아가면 방금 조사한 제품을 찾기 위해 스크롤 한 다음 해당 지점에서 새로 제품을 찾아야합니다.

제품 목록에서 올바른 위치를 다시 찾는 이 추가 단계는 대규모 사용성 테스트 동안 사이트 포기직접적인 원인으로 관찰되었습니다.

즉, 사용자가 사이트를 이탈하게 되는 직접적인 원인 인 것입니다.

그렇게 되면 사용자를 잃게 되고 매출에도 영향이 갈 수 있는 문제입니다.

또한 사용자는 여러 개의 제품을 보고 뒤로가기로 이동하면 계속해서 제품 목록의 최상위에 위치하게 되면, 인내심잃을 가능성이 큽니다.

(사용자가 뒤로가기 시 스크롤이 유지되도록 기대 하는지에 대한 통계)

출처: https://baymard.com/blog/return-same-place

위의 이야기들을 살펴보면 상세 페이지에서 리스트 페이지로 이동하게 되었을 때 스크롤이 유지가 되지 않는다면 얼마나 큰 손해를 가져올지 알 수 있습니다.

저희 원티드랩 뿐만 아니라 당근마켓, 오늘의집 등 다른 기업들도 뒤로가기를 했을 때 스크롤 위치와 제품(Item) 수를 유지하려고 많은 노력을 가하고 있습니다.

많은 방법들 중 저희는 Route as Modal 을 접목시켜 보기로 했습니다.

Route as Modal?

Route as Modal은 리스트 페이지에서 상세 페이지로 이동할 때 Route(URL)를 이용하여 리스트 페이지에서 Modal로 상세 페이지를 보여주는 것을 말합니다.

Next.js 예제 참고

이 글 하단에도 예시가 있습니다.

결과

AS-IS

기존 커리어성장 페이지

뒤로가기 했을 때 원래 리스트페이지의 스크롤만 기억하여 다시 그 스크롤으로 내려주는 모습을 볼 수 있습니다. (데이터는 계속 새로 불러옴..)

TO-BE

뒤로가기 상태유지 해결 후 커리어성장 페이지

리스트 페이지에 조건부로 Modal만 표시하면 되기 때문에 뒤로가기 했을 때에도 리스트페이지로 동일하여 상태, 스크롤 유지가 쉽게 됩니다!

추가

위처럼 적용하면 간단하게 되지만 SSR (서버 사이드 렌더링) 문제와, 링크로 바로 들어온 사용자를 고려할 때

링크로 바로 들어온 사용자는 리스트 페이지에서 Modal로 보여지는게 아닌, 상세 페이지 접속에 포커싱을 두는게 좋을 것 같아 몇가지 추가 해보았습니다.

현재 커리어성장 페이지

원티드 ‘커리어 성장’ 리스트에서 아이템 클릭 시에는 모달로 표시되고 바로 새로고침을 하면 인페이지 형태로 표시되는 것을 볼 수 있습니다.

즉, 리스트 페이지에서 접속 했을 때의 상세 모달과 상세 페이지가 분리가 되어 있습니다.

하지만 주소창을 자세히 살펴보면 모달로 표시될 때 이미 인페이지 형태의 URL로 변경이 됩니다.

작동 원리

동작 구조

Next.jsas 기능을 사용하면 실제 브라우저에서 표시되는 URL 만 수정이 가능합니다. 🤭 (Next.js 9.5.3 이후)

브라우저 상에서 URL은 상세 페이지의 URL인데, 실제로는 href 를 이용해서 리스트 페이지에 쿼리를 넘겨줍니다.

그렇게 되면 리스트 페이지에서 쿼리 여부에 따라 모달을 보여주고, 상세 페이지는 따로 해당 라우트에 맞게 개발해줍니다.

Next.js가 아닌 React.js 에서도 구현이 가능합니다.
https://reactrouter.com/web/example/modal-gallery

as, href를 포함한 동작 구조

파란색 글씨내부적으로 동작하는 경로, 빨간색 글씨브라우저 상에서 보여지는 경로입니다.

리스트 페이지에서 모달로 상세정보를 보여줄 때에는 as 를 이용하여 임의로 일종의 눈속임을 통하여
실제로는 리스트 페이지에서 쿼리만 바뀐 것인데, 상세 페이지로 마치 이동한 것 처럼 URL을 설정해줍니다.

그 이후 새로고침을 하면 (또는 URL로 바로 접근 시) 임의로 눈속임을 적용한 것이 없기 때문에 해당 라우트에 맞는 페이지 정보가 보여지게 됩니다.

아래 예시에서 상세하게 확인할 수 있습니다.

예시

아래 코드 예시는 리스트 페이지 → /events 상세 페이지 → /events/[id] 일 경우 입니다.

그 이후 Item 컴포넌트에서 href로 넘긴 쿼리 값 여부에 따라 리스트 페이지에서 모달을 보여줍니다.

마지막으로 상세 페이지에서 인페이지 컴포넌트를 표시합니다.

마치며

사소한 것부터 사용자 측면을 고려하면서 개선해 나간다면 더 많은 사용자를 유지할 수 있고,
반대로 사용자 측면을 고려하지 않는다면 더 많은 사용자를 잃게 됩니다.

앞으로도 프론트엔드 팀에서 사용성을 개선 하도록 꾸준히 노력하겠습니다!

이 글도 한번씩 읽어보시면 사용자의 경험이 얼마나 중요한지 다시금 새길 수 있을 것 같습니다.

글 읽어주셔서 감사합니다 🙇‍♂️

원티드에서는 다양한 직군에서 적극적으로 채용중입니다! 서버, 웹, 앱, 디자인 등 제품을 만들어가는 각자의 분야에서 전문적인 분들과 함께 일하기를 기대하고 있습니다. 회사 채용 정보 페이지를 확인해 주세요!

--

--