본문으로 건너뛰기
Projects

Few Letter

AI가 요약한 뉴스를 카테고리별로 골라 이메일로 받는 구독 서비스입니다.

웹에서는 국내 · 해외 뉴스를 카테고리별로 모아 봅니다.

현재는 운영이 종료된 서비스입니다. 아래의 화면은 목업으로 구성되어 있습니다.

  • Next.js 16 App Router
  • React 19
  • TypeScript
  • TanStack Query 5
  • Tailwind CSS 4
상단에 데일리 few 캐러셀이 있고 그 아래로 세로 카테고리 사이드바와 3열 뉴스 카드가 놓인 데스크톱 화면
국내 뉴스 홈. 위쪽 데일리 few 캐러셀 아래로 한줄 요약 목록이 이어집니다.

통신 레이어

로깅, 에러 변환, 쿼리 조립처럼 매 호출에 반복되던 일을 한 레이어가 전담합니다.

외부 HTTP 라이브러리 대신 fetch를 감싼 클라이언트를 두고 요청 · 응답 · 에러 세 지점에 미들웨어를 끼울 수 있게 해, 호출처에는 경로와 응답 타입만 남겼습니다.

구독 폼의 제출 흐름. 이메일 형식과 카테고리 선택이 모두 맞아야 버튼이 열립니다.

데이터 페칭

쿼리 정의를 한 곳에 모아 서버 프리페치와 클라이언트 훅이 그대로 나눠 씁니다.

키와 페칭 함수와 캐시 정책을 한 곳에서만 정의해, 서버에서 미리 받아 둔 부분은 로딩 없이 그려지고, 키가 어긋나 프리페치가 버려지는 사고가 나지 않습니다.

국내에서 해외로 이동. 월드가 바뀌면 쿼리 키가 갈려 목록을 새로 가져옵니다.

목록 화면

목록을 offset이 아닌 커서 방식으로 붙입니다.

커서로 마지막 항목의 id를 보내서, 새 글이 들어와도 페이지 경계에서 항목이 중복되거나 누락되지 않습니다. 로딩 · 에러 · 빈 목록 · 정상 네 상태는 모두 화면으로 만들었습니다.

스크롤에 따라 다음 커서의 카드가 이어 붙습니다. 날짜가 끊기지 않습니다.
좌측 카테고리 목록은 렌더된 상태에서 카드 영역만 회색 스켈레톤으로 표시된 화면
캐시가 없는 첫 진입. 카테고리는 서버에서 받아 이미 그려져 있고, 카드만 스켈레톤입니다.

반응형 캐러셀

슬라이드 이동과 인디케이터가 반응형으로 지원되는 캐러셀을 라이브러리 없이 직접 구현했습니다.

항목 타입은 제네릭으로, 렌더링은 호출부가 넘긴 함수로 받아 어떤 목록에든 쓸 수 있습니다. 화면 폭에 따라 한 번에 보이는 개수가 바뀌는데, 나누어떨어지지 않으면 마지막 슬라이드의 이동량을 보정해 빈 칸을 없앴습니다. 터치 스와이프는 최소 이동 거리를 두어 세로 스크롤과 섞이지 않게 했습니다.

화살표로 슬라이드를 이동하면 하단 인디케이터의 폭과 위치가 함께 갱신됩니다.

반응형

폭이 줄면 열 개수와 내비게이션 형태를 바꿉니다.

좁은 화면에서 헤더는 햄버거 메뉴가 됩니다. 넓은 화면에서는 탭과 구독 링크를 펼칩니다.

데스크톱 폭에서 헤더에 탭과 구독 링크가 펼쳐지고, 왼쪽 세로 카테고리 사이드바 옆으로 3열 뉴스 카드가 놓인 화면
1440px. 탭과 구독 링크가 모두 펼쳐지고 카테고리는 왼쪽 세로 사이드바, 카드는 3열입니다.
태블릿 폭에서 헤더에 국내·해외 탭과 구독 링크가 펼쳐지고 카테고리는 가로 칩, 카드는 2열로 놓인 화면
768px. 헤더는 데스크톱과 같고 카테고리만 가로 칩, 카드는 2열입니다.
모바일 폭에서 헤더가 로고와 햄버거 버튼만 남고 캐러셀이 한 장, 카테고리 칩이 두 줄로 놓인 화면
390px. 탭과 구독 링크가 햄버거로 접히고 캐러셀은 한 장씩 넘깁니다.