-
[Next.js] 프로젝트에 PWA 적용하기React 2024. 5. 28. 14:15
최근에 지도 서비스를 개발하면서 사용자들이 해당 서비스를
모바일에서 보다 편리하게 사용할 수 있도록 PWA를 적용하기로 했습니다.
오늘 포스팅에서 Next.js에서 PWA를 적용했던 과정을 적어보려 합니다.
| manifest.ts
먼저 pwa를 적용하기 위해서는 manifest라는 json 파일을 통해서 앱의 이름, 아이콘,
기타 설명 등등을 설정해 줘야 사용할 수 있습니다.
따라서 우선적으로 해야 할 부분은 manifest파일을 만들고, 설정을 입력하고,
html의 head태그 안에 아래와 같이 link태드를 넣어주면 됩니다.
<link rel="manifest" href="/manifest.json">
하지만 Next.js에서는 직접 manifest.json을 만들고 link를 걸어줄 필요가 없고,
공식문서를 보면 manifest.ts파일을 통해 자동으로 manifest를 생성하고,
자동으로 link태그로 추가해 준다고 합니다.
https://nextjs.org/docs/app/api-reference/file-conventions/metadata/manifest
Metadata Files: manifest.json | Next.js
API Reference for manifest.json file.
nextjs.org
따라서 우선 프로젝트의 app폴더 내에 manifest.ts 파일을 만들고
만들고 있는 앱의 설정을 넣어주겠습니다.
import { MetadataRoute } from "next"; const manifest = (): MetadataRoute.Manifest => { return { theme_color: "#222", background_color: "#222", display: "standalone", scope: "/", start_url: "/", name: "철봉 지도", short_name: "철봉 지도", description: "주변 철봉 위치를 확인하세요", lang: "ko-KR", icons: [ { src: "/logo192.png", sizes: "192x192", type: "image/png", purpose: "maskable", }, { src: "/logo512.png", sizes: "512x512", type: "image/png", }, ], }; }; export default manifest;
여기서 display속성으로 스마트폰에서 앱을 받았을 때 어떤 식으로 보여줄지를 정할 수 있습니다.
자세한 내용은 아래 링크를 참고하면 되고, 일반적으로 standalone을 사용한다고 하여
저도 standalone을 사용하였습니다.
https://developer.mozilla.org/en-US/docs/Web/Manifest/display
display - Web app manifests | MDN
The display member is a string that determines the developers' preferred display mode for the website. The display mode changes how much of browser UI is shown to the user and can range from browser (when the full browser window is shown) to fullscreen (wh
developer.mozilla.org
이때 standalone을 사용하면 아이폰에서 볼 때 화면 위쪽에 카메라 때문에 약간의 여백이 생깁니다.
해당 여백의 색상은 manifest의 theme_color를 통하여 지정할 수 있습니다.
그리고 icons에 purpose에 maskable 속성이 있는데 이는 아이콘을 자르거나
모양을 변경하지 않고도 다양한 크기와 모양의 디바이스에서 잘 보일 수 있도록 디자인된
아이콘을 말합니다.
그럼 이제 로컬 환경에서 프로젝트를 실행시켜 보면
상단에 이런 식으로 다운로드할 수 있는 아이콘이 생기게 됩니다.
이런 식으로 pwa 적용이 완료되었습니다.
| manifest 401 에러
pwa적용을 완료하고 실제 배포된 주소에 적용을 했을 때
다음과 같은 401 에러가 발생하였습니다.
찾아보니 link태그의 crossorigin 속성을 use-cresdentials로 줘서
자격증명을 포함시키도록 하면 해결이 된다고 하여 이를 적용해보려 했습니다.
next.js에서는 head태그내부의 태그들에 crossOrigin 속성을
next.config.ts 파일에서 설정할 수 있습니다.
module.exports = { crossOrigin: 'use-credentials', }
이런 식으로 설정을 주고 다시 실행시켜 봤는데
link태그로 연결되어 있는 manifest만 use-credentials가 적용이 안 되는 문제가 발생했습니다.
따라서 다른 방법을 찾아보기로 했습니다.
| next-pwa
다시 원점으로 돌아가서 next.js에서 pwa를 어떻게 적용하는 게 좋을지 찾아보다가
next-pwa라는 라이브러리가 있다는 것을 알았습니다.
https://github.com/shadowwalker/next-pwa
GitHub - shadowwalker/next-pwa: Zero config PWA plugin for Next.js, with workbox 🧰
Zero config PWA plugin for Next.js, with workbox 🧰 - shadowwalker/next-pwa
github.com
이번에는 이 라이브러리를 사용하여 pwa를 적용해보려 합니다.
우선 next.config.ts 파일에서 해당 라이브러리를 import해온다음
설정을 작성해 주고 리턴합니다.
/** @type {import('next').NextConfig} */ import withPWA from "next-pwa"; const nextPWA = withPWA({ dest: "public", }); const nextConfig = { ...설정들 }; export default nextPWA(nextConfig);
이런 식으로 한 후 public 폴더에 manifest.json 파일을 하나 만들어 줍니다.
다음, manifest 설정을 입력합니다.
{ "theme_color": "#222", "background_color": "#222", "display": "standalone", "scope": "/", "start_url": "/", "name": "철봉 지도", "short_name": "철봉 지도", "description": "주변 철봉 위치를 확인하세요", "lang": "ko-KR", "icons": [ { "src": "/logo192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { "src": "/logo512.png", "sizes": "512x512", "type": "image/png" } ] }
그리고 마지막으로 layout에 head태그를 포함시키고
아래와 같이 link태그로 연결해 줍니다.
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
이런 식으로 코드를 작성한 후
다시 배포해 보니까 이 번에는 pwa가 잘 적용이 되었습니다.
| No theme-color tag found
이제 사이트를 lighthouse를 통해 검사해 보면 다음과 같이 설치 가능이라고 나옵니다.
하지만 아래로 좀 내려보면
이런 문구가 보이는 것을 확인할 수 있습니다.
이는 간단하게 해당 태그를 추가해 주면 해결됩니다.
next.js14 버전 이후 기준으로
메타 태그를 설정할 때
export const metadata: Metadata = { ... };
다음과 같은 함수를 통하여 생성하게 됩니다.
하지만 next.js의 공식문서를 보면 theme-color는 해당 함수 내부에서 설정하는 것이 아닌
따로 viewport 객체를 만들어서 생성해 줘야 합니다.
https://nextjs.org/docs/app/api-reference/functions/generate-viewport
Functions: generateViewport | Next.js
API Reference for the generateViewport function.
nextjs.org
따라서 layout 파일에 아래와 같이 코드를 작성해 주어서 해결하였습니다.
export const viewport: Viewport = { themeColor: "#222", };
'React' 카테고리의 다른 글
[vite.js / react] yarn berry 사용하기 (vscode 타입스크립트 오류) (0) 2024.07.14 무한 스크롤을 구현하기 위한 몇 가지 방법들 (Intersection Observer API를 사용하는 이유) (1) 2024.06.17 [Next.js, React(vite.js)] 로컬 개발 환경 https 적용하기 (0) 2024.05.02 [React] next.js ssr api요청에 쿠키 포함해서 보내기 (0) 2024.04.19 Vite.config에 환경변수 넣기 (0) 2024.04.15