sw.js 만들기 (next-pwa)
pwa를 배포하기 위해서는 service-worker.js 파일에 이벤트 리스너를 추가해주어야 한다. 여기에는 'install', 'activate', 'fetch' 등이다.
이러한 작업을 zero-config로 도와주는 라이브러리가 next-pwa이다.
-
설치
yarn install next-pwa
-
next.config.js
const withPWA = require("next-pwa")({
dest: "public",
});
const nextConfig = withPWA({
reactStrictMode: true,
compiler: {
styledComponents: true,
},
});
module.exports = nextConfig;
withPWA를 만든 후, 이를 통해 기존 config를 감싸면 간단하게 sw.js를 만들어준다.
manifest.json
서비스 워커에서 핵심적인 것은 manifest이다.
어플리케이션처럼 동작하기 위한 메타데이터를 저장한 파일이다.
{
"name": "CS 퀴즈풀기",
"short_name": "CS 퀴즈풀기",
"icons": [
{
"src": "/favicon.jpg",
"sizes": "256x256",
"type": "image/png",
"purpose": "any maskable"
}
],
"theme_color": "#FFFFFF",
"background_color": "#FFFFFF",
"start_url": "/",
"display": "standalone",
"orientation": "portrait"
}
아이콘을 설정하고, 아이콘이 작게 표기될 때 백그라운드에 표시될 색깔, 어플리케이션 이름 등을 설정한다.
여기서 "display": "standalone",
부분이 중요한데, 이 설정을 통해 웹 페이지가 모바일 어플리케이션처럼 보이게 된다.
메타태그 작성하기
메타 태그는 _document.tsx나 _app.tsx에 작성하면 된다.
_document.tsx에서는 메타데이터에서 title을 설정할 수 없기 때문에 편의상 _app.tsx에서 작성하였다.
대표적인 메타 태그는 아래와 같다.
<link rel="manifest" href="/manifest.json" />
: 메니페스트 파일을 연결시킨다.
meta name="viewport" content="initial-scale=1, viewport-fit=cover, width=device-width"></meta>
: viewport를 가득 채운다. standalone 모드가 제대로 작동하지 않을 때 보조적인 역할을 한다.
<meta name="apple-mobile-web-app-capable" content="yes"></meta>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"></meta>
: 노치 디자인을 채우기 위해 뻘짓하다 발견한 돗이다. bar-style를 black-translucent로 지정하면 웹의 배경화면 설정으로 노치를 채우게 된다. default값은 노치 부분을 가려서 화면이 제한된다. 다음 글을 참조하자. Make your pwa look handsome on ios
이것저것 쳐내고 남은 메타태그는 아래와 같다.
<Head>
<title>CS 문제 풀기</title>
<meta name="description" content="CS 문제를 자유롭게 풀어봐요" />
<link rel="icon" href="/favicon.ico" />
<link rel="manifest" href="/manifest.json" />
<meta name="application-name" content="CS 퀴즈풀기" />
<meta
name="viewport"
content="initial-scale=1, viewport-fit=cover, width=device-width"
></meta>
<meta name="apple-mobile-web-app-capable" content="yes"></meta>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
></meta>
<meta name="apple-mobile-web-app-title" content="CS 퀴즈풀기" />
<meta name="description" content="CS 문제를 마음대로 풀어보세요" />
<meta name="format-detection" content="telephone=no" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="msapplication-TileColor" content="#2B5797" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="/favicon.jpg" />
<link rel="mask-icon" href="/favicon.jpg" color="#5bbad5" />
<link rel="shortcut icon" href="/favicon.ico" />
</Head>
노치 화면 채우기
앞서 언급했듯, 애플은 PWA에서 노치 화면을 감추거나(default), 완전히 열어두게(translucent) 된다.
black-translucent로 노치를 열어두고, 노치의 높이만큼 padding을 채우면 원하는 디자인으로 노치를 꾸밀 수 있다.
export const StyledTextHeader = styled.div`
position: sticky;
top: 0;
padding: 0.5rem 1rem;
padding-top: calc(0.3rem + env(safe-area-inset-top));
설치 안내 문구 띄우기
랜딩 페이지에서 PWA를 설치하는 버튼을 만들고자 했는데,
안드로이드에서도 아이폰에서도 설치 버튼이 작동되지 않았다.
PWA 여부와 OS 종류를 감지하여 그에 맞는 문구를 띄워주기로 했다.
components\common\molecules\HomeScreenMessage.tsx
import { useEffect, useState } from "react";
const HomeScreenMessage = () => {
const isAndroid =
typeof window !== "undefined" &&
/android/i.test(window.navigator.userAgent);
const isiOS =
typeof window !== "undefined" &&
/iphone|ipad|ipod/i.test(window.navigator.userAgent);
const [msg, setMsg] = useState("");
useEffect(() => {
if (isiOS) {
setMsg(
'아이폰 브라우저에서는 "공유" 버튼을 눌러 홈 화면에 추가할 수 있습니다.'
);
} else if (isAndroid) {
setMsg(
'안드로이드 브라우저에서는 "홈 화면에 추가" 또는 "추가" 버튼을 눌러 홈 화면에 추가할 수 있습니다.'
);
}
}, []);
if ((isAndroid || isiOS) && !window.navigator.standalone) {
return (
<div style={{ fontSize: "x-small", color: "gray" }}>
<div>
<b>홈 화면에 바로가기를 추가해보세요. </b>
</div>
<span>{msg}</span>
</div>
);
}
return null;
};
export default HomeScreenMessage;
declare global {
interface Navigator {
standalone?: boolean;
}
}
pages\index.tsx
<Description>
<HomeScreenMessage></HomeScreenMessage>
</Description>
</Main>
</Container>
);
}
배포하기
vercel로 배포하면 된다.
배포된 주소는 이곳이다. (나름 희귀한 도메인을 얻었다.)
모바일로 접속하면 아래에 홈 화면에 추가하라는 문구가 나온다.
'홈 화면에 바로가기 만들기'를 하면 pwa가 설치된다.
이렇게 해서 완성이 완료됐다.