Connection
사용 기술
- Next
- (App Router) SEO 최적화를 위한 동적 메타 데이터 생성, 서버 사이드 렌더링을 포함한 서버 컴포넌트, 링크 사전 가져오기(Link prefetch), 이미지 최적화 (Image), 경로 처리(Route Handler), 경로 가로채기(Intercepting Routes), 병렬 경로 처리(Parallel Routes) 등의 고급 기능을 활용하기 위해 사용하였습니다.
- TypeScript
- 컴파일 단계에서 타입 오류를 사전에 발견하여 프로젝트의 안정성을 높이기 위해 사용하였습니다.
- Tailwind CSS
- 서버 컴포넌트에서 CSS를 사용하기 위해 zero-runtime 특성이 있는 Tailwind CSS를 선택했습니다.
- Zustand
- 사용이 간단하고 가볍고 간결한 코드로 전역 상태 관리가 가능하여 선택하였습니다.
- React Query
- 서버 상태 관리를 간소화하고 불필요한 네트워크 요청을 줄이며, 데이터 페칭, 캐싱, 동기화 및 서버 상태 업데이트를 편리하게 처리할 수 있도록 도입하였습니다.
- React Table
- 성능 최적화와 유연한 커스터마이징이 가능해 데이터 테이블을 쉽게 구성하고 관리하기 위해 사용하였습니다.
- React Hook Form
- 회원가입, 강사 등록, 클래스 작성 시 등 복잡한 폼 데이터의 효율적 관리와 유효성 검사를 위해 사용하였습니다.
- Framer Motion
- React 애니메이션 라이브러리로, 부드럽고 자연스러운 애니메이션을 구현하기 위해 사용하였습니다.
- Naver Api
- 네이버 지도 및 네이버 소셜 로그인 기능을 위해 사용하였습니다.
- Firebase
- Service worker를 이용하여 웹 푸쉬 알림을 도입하기 위해 사용하였습니다.
- PWA
- 프로그레시브 웹 애플리케이션을 구현하여 네이티브 앱과 유사한 사용자 경험을 제공하기 위해 사용하였습니다.
- Socket.io
- 실시간 양방향 통신을 구현하여 실시간 채팅, 알림 등의 기능을 제공하기 위해 사용하였습니다.
- Jest
- 단위 테스트와 통합 테스트를 효율적으로 작성하고 안정성을 높이기 위해 사용하였습니다.
- Vercel
- 프론트엔드 애플리케이션을 배포하고, 자동화된 CI/CD 파이프라인을 구성하기 위해 사용하였습니다.
- Docker
- 컨테이너 기술을 사용하여 애플리케이션의 환경 일관성을 유지하고, 배포와 스케일링을 용이하게 하기 위해 사용하였습니다.
- GitHub Actions
- 자동화된 워크플로우를 설정하여 CI/CD 파이프라인을 구축하고, 코드 품질을 유지하기 위해 사용하였습니다.
- Sentry
- 에러 모니터링과 로그 수집을 위해 도입하였습니다. 디스코드 웹훅과 연동하여 에러 상황을 모니터링하고 대응하였습니다.
- StoryBook
- 컴포넌트의 문서화 및 디자이너와의 효율적인 협업을 위해 사용하였습니다.
- Eslint
- 팀원과의 코드 품질과 일관성을 유지하기 위해 코드 린팅 도구로 사용하였습니다.
개발 과정
Storybook을 활용한 컴포넌트 문서화 및 UI 리뷰 간편화
검색 필터 및 검색 페이지 구현
트러블 슈팅
이슈: 검색 아이템 페이지로 이동 후 기존 검색 페이지로 복원 시 무한 스크롤 아이템이 사라져 scrollRestoration이 되지 않는 문제
Next.js는 기본적으로 뒤로 가기 및 앞으로 가기 탐색 시 스크롤 위치를 자동으로 복원합니다. 그러나 기존에는 클라이언트 컴포넌트 내의 상태(state)에만 아이템을 저장했기 때문에, 검색 아이템 페이지로 이동 후 다시 돌아왔을 때 아이템이 사라져 스크롤 복원이 되지 않는 문제가 발생했습니다. 이를 해결하기 위해 react-query의 useInfiniteQuery를 사용하여 무한 스크롤을 구현하고, 검색 아이템을 react-query에 캐싱 하여 기존 페이지로 복원 시 기존 아이템이 유지되도록 변경했습니다.
수강생 및 강사 리뷰 관리 페이지
좋아요 및 차단 (강사 & 클래스)
트러블 슈팅
이슈: 강사 & 클래스 상세 페이지 방문 후 preview에서 관심 표시 진행 시 표시가 되지 않는 이슈
강사 & 클래스 상세 페이지 방문 후 preview에서 관심 표시를 하면 Next.js의 fetch cache 기능 때문에 좋아요 표시가 되지 않는 문제가 발생했습니다. 이를 위해 관심 표시한 강사와 클래스의 id를 react-query의 전역 상태로 관리하고, Like 컴포넌트가 이 전역 상태를 구독하여 동기화함으로써 해결했습니다.
수강생 관리 페이지
쿠폰 사용
쿠폰 관리
패스권 구매 및 사용
패스권 관리
헤더 컴포넌트
트러블 슈팅
이슈: 헤더 컴포넌트의 프로필이 페이지 이동 및 새로고침 시 Hydration Delay 동안 비로그인 상태처럼 보이는 문제
Zustand Store에 유저 정보를 저장하고, 해당 유저 정보를 프로필 컴포넌트가 구독하여 조건부 렌더링을 수행합니다. 이로 인해 pre-rendering 단계에서는 로그인 이전 상태로 보이게 되고, hydration이 완료된 후에야 Zustand 유저 Store가 업데이트되면서 Hydration Delay 동안 비로그인 상태처럼 보이게 됩니다.
이 문제를 해결하기 위해, 프로필 컴포넌트가 Zustand 상태에 의존하지 않도록 하고 서버 컴포넌트에서 유저 정보를 props로 전달받아 프로필 컴포넌트도 pre-rendering이 되도록 구현했습니다.
회원 정보 수정
지도 공통 컴포넌트 구현
네이버 소셜 로그인 및 회원가입 구현
실시간 채팅
실시간 알림
클래스 등록 페이지
트러블 슈팅
이슈: 각 섹션의 파일 번들 크기가 과도하게 크다는 문제가 있었습니다.
Dynamic Import 기술을 적용하여 필요한 섹션만을 실시간으로 로드하도록 최적화하였습니다. 이 접근 방식은 전체 페이지의 로딩 시간을 단축시키고, 성능을 크게 향상시켰습니다. 사용자는 더 빠르고 원활한 인터페이스를 통해 클래스를 효율적으로 등록할 수 있게 되었습니다.
PWA 연결 및 설치 방법 페이지
FCM 연결 및 웹 푸쉬 알림 구현
트러블 슈팅
이슈: Next.js의 public 폴더 내에서 환경 변수(env) 사용 시 'ReferenceError: process is not defined'라는 에러 발생
Next.js의 public 폴더 내에서 환경 변수를 사용할 때 발생하는 이슈로, Firebase의 Service Worker가 Next.js의 public 폴더 내에서 작동하기 때문에 발생하는 문제였습니다. 이 문제를 해결하기 위해 dotenv 패키지를 사용하여 빌드 시점에 process.env의 내용을 가져와 Firebase의 키값을 안전하게 숨길 수 있게 되었습니다. 이 방법을 통해 Firebase 키를 효율적으로 관리하며 보안성을 높일 수 있었습니다.
강사 등록 페이지
강사 상세 페이지
트러블 슈팅
이슈: Next.js에서 동적 메타 데이터 생성 시 중복 API 요청으로 인한 서버 리소스 낭비
Next.js에서 동적 메타 데이터를 생성하는 과정에서, generateMetadata 함수와 Page 컴포넌트가 각각 별도로 API 요청을 수행하게 되었습니다. 이로 인해 동일한 API 요청이 두 번 발생하여 서버 리소스의 낭비가 발생했습니다. 이러한 문제를 해결하기 위해 React Cache를 사용하여 fetch 요청의 결과를 캐시하고 동일한 데이터를 재사용하는 방법을 도입했습니다. 이 방법을 통해 단 한 번의 요청으로 데이터를 획득하고, 해당 데이터를 페이지와 generateMetadata 함수에 모두 전달할 수 있게 되었습니다.