설치 가능한 PWA 자격을 갖추는 최소 셋: - web/public/manifest.webmanifest: 한국어 name/short_name, 다크 테마 컬러, standalone display, /icon.svg (any maskable, sizes any) - web/public/icon.svg: 다크 배경 + 한국 컬러 캔들(상승=#ef4444 / 하락=#3b82f6) + 우상향 추세선. maskable safe-zone (중심 80%) 보존 - web/public/sw.js: install/activate 만 처리 (fetch handler 없음). install 자격만 충족하고 네트워크는 그대로 통과 → 캐시 stale 위험 0 - web/components/PwaRegister.tsx: production 빌드에서만 SW 등록, 실패는 silently 무시 - web/app/layout.tsx: Metadata.manifest/icons/appleWebApp, viewport.themeColor/colorScheme 분리 (Next 14 권장) dev (next dev) 에서는 SW 등록을 우회 — HMR 응답 간섭 회피.
22 lines
849 B
TypeScript
22 lines
849 B
TypeScript
"use client";
|
|
|
|
// 최소 서비스워커 등록.
|
|
// - production 빌드에서만 등록 — dev (next dev / HMR) 환경에선 SW 가 HMR 응답을
|
|
// 이상하게 가로채는 케이스가 있어 의도적으로 우회.
|
|
// - 등록 실패는 silently 무시 (Safari private mode, http://0.0.0.0 같은 secure context
|
|
// 아닌 호스트, 브라우저 정책 거부 등). PWA install 자격만 못 갖출 뿐 앱 기능엔 영향 없음.
|
|
|
|
import { useEffect } from "react";
|
|
|
|
export function PwaRegister() {
|
|
useEffect(() => {
|
|
if (typeof window === "undefined") return;
|
|
if (!("serviceWorker" in navigator)) return;
|
|
if (process.env.NODE_ENV !== "production") return;
|
|
navigator.serviceWorker.register("/sw.js").catch(() => {
|
|
/* noop — 등록 실패 시 PWA 기능만 비활성. */
|
|
});
|
|
}, []);
|
|
return null;
|
|
}
|