대학교 공지사항 알림 서비스
대학교 홈페이지에 올라오는 수많은 공지사항들,
중요한 내용이지만 매번 직접 확인하기는 번거롭습니다.
univon은 학교의 공지사항을 자동으로 수집하고,
사용자가 관심 있는 키워드 기반으로 알림을 받을 수 있도록 도와주는 서비스입니다.
⭐️ 메인 페이지 / 학교 설정 / 키워드 설정 / 알림 설정
- 메인 페이지 : 설정한 학교의 모든 공지사항을 확인 가능합니다.
- 학교 설정 : 사용자가 직접 학교를 선택하고 해당 학교의 공지사항만 확인 가능합니다.
- 키워드 설정 : 관심 있는 공지를 키워드 기반으로 필터링할 수 있으며, 키워드는 자유롭게 추가/삭제 가능합니다.
- 알림 설정 : 알림 여부를 ON/OFF로 제어할 수 있어, 알림 수신 여부를 설정 가능합니다.
- 공지사항 목록은
Infinite Scroll로 구현,React Query + useInfiniteQuery를 사용해 구현 - 스크롤 위치에 따라 새로운 페이지 자동 요청 (
react-intersection-observer활용) - 사용자의 화면에 있지 않은 컴포넌트는
@tanstack/react-virtual을 활용하여 가상화하여 최적화
- 기본적인 HTTP 통신을 통해 사용자 설정 정보를 서버와 통신
Notification.permission상태와FCM 토큰을 확인해 알림 ON/OFF를 컨트롤- 알림 설정 데이터는
FCM 토큰,알림 ON/OFF,키워드,학교 ID를 조합하여 서버에 저장
![]() 메인 공지사항 페이지 |
![]() 학교 설정 페이지 |
![]() 키워드 설정 페이지 |
![]() 알림 ON/OFF 설정 |
⭐️ FCM 알림
- 새로운 공지사항이 생기면 푸시 알림이 발송됩니다.
- 키워드와 학교 조건에 따라 맞춤 알림을 제공합니다.
Firebase Cloud Messaging (FCM)사용- 클라이언트에서 알림 권한 동의 시 FCM 토큰을 발급받아 서버에 저장
- 서버는 키워드와 학교 조건에 맞는 유저를 필터링하여 알림 전송
![]() 푸시 알림 페이지 |
⭐️ PWA
- 모바일에서도 앱처럼 사용할 수 있도록 PWA를 지원합니다.
- 홈 화면에 설치해 앱처럼 실행 가능합니다.
next-pwa사용- 매니페스트 설정 (
manifest.json) - 홈 화면 설치를 위한 설치 프롬프트 처리
![]() PWA 설치 안내 |
선언적 UI 구성
<serverFetchBoundary>와<Suspense>로 감싸서 로딩/에러/데이터 상태를 선언적으로 처리- 에러 상태는
error.tsx를 활용하여 에러 처리
<Suspense fallback={<div>로딩 UI</div>}>
<ServerFetchBoundary fetchOptions={userKeywordListQueryOptions()}>
<KeywordInputForm />
<KeywordChipList />
</ServerFetchBoundary>
</Suspense>QueryClient 즉시실행함수 + 싱글턴 패턴
- QueryClient를 싱글턴 패턴으로 관리하여 클라이언트에서는 하나의 인스턴스를 재사용
- 서버에서는 매 요청마다 새 인스턴스를 생성해 SSR 환경에 적합하도록 함
export const queryClientSingleton = (function () {
let instance: QueryClient | undefined = undefined
function createQueryClientInstance() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: DEFAULT_STALE_TIME,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
retry: 0,
},
dehydrate: {
shouldDehydrateQuery: (query) =>
defaultShouldDehydrateQuery(query) ||
query.state.status === 'pending',
},
},
})
}
return {
getInstance: function (): QueryClient {
if (isServer) {
return createQueryClientInstance()
}
if (!instance) {
instance = createQueryClientInstance()
}
return instance
},
}
})()서버 통신 훅 및 옵션 관리
- 서버 컴포넌트에서
ServerFetchBoundary를 활용하여 미리 데이터 패칭 후 클라이언트 컴포넌트에서 캐시된 데이터 사용 - 통신 요청을 커스텀 훅(
useQuery,useMutation)으로 분리 - 내부 로직은
queryOptions,mutationOptions객체를 활용하여 재사용 가능하게 구성
🔗 현재 배포 주소 : https://www.univ-on.com/
🔗 리팩토링 이전 깃허브 주소 : https://github.com/Head-4/Head-4-FE-VITE
| 성지훈 (Front-end) | 박준형 (Back-end) | 엄지호 (Back-end) |
|---|






