Next.js에 PWA 적용하기
Next.js 프로젝트에 PWA 적용하기
PWA란 ?
PWA는 Progressive Web Apps 의 줄임말로 네이티브앱과 유사한 사용자 경험을 제공하면서 웹의 장점을 동시에 가지고 있는 기술입니다.
사용자가 사이트에 접근했을 때 App과 유사한 형태로 다운로드를 받도록 유도할 수도 있고, 오프라인에서도 캐싱된 데이터를 가지고 앱을 작동시킬 수도 있습니다. 또, 푸시 알림도 구현되어 있어서 사용자에게 알림 데이터를 보내줄 수도 있습니다.
자세한 내용은 프로그레시브 웹 앱이 무엇인가요? 를 참고하세요.
PWA을 적용하기 위한 기본 요건
- https 지원
- service-worker 사용
- manifest 작성
- 앱 아이콘 등록
Next.js 프로젝트에 PWA 적용
Next.js로 제작된 프로젝트를 이미 가지고 있으며, https는 적용되어 있는 상태로 가정하고 작성합니다.
-
devDependencies에 sw-precache-webpack-plugin 추가
sw-precache-webpack-plugin은 build시 .next/static/ 위치에 service-worker.js를 자동으로 생성해 줍니다.
npm install --save-dev sw-precache-webpack-plugin
-
웹팩 설정
/next.config.js
var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin'); module.export = { ..., webpack : (config, {dev}) => { ...; if(!dev){ config.plugins.push( new SWPrecacheWebpackPlugin({ staticFileGlobsIgnorePatterns: [/\.next\//], minify: true }) ) } } }
-
service-worker.js 라우팅 설정
/server.js (서버파일)
const express = require('express'); const next = require('next'); const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev }); const port = parseInt(process.env.PORT, 10) || 3000; const handle = app.getRequestHandler(); app.prepare().then(() => { const server = express(); const path = require('path'); server.get("/service-worker.js", (req, res) => { const filePath = path.join(__dirname, '.next', 'service-worker.js') app.serveStatic(req, res, filePath); }); server.get('*', (req, res) => { return handle(req, res); }); server.listen(port, (err) => { if (err) throw err; console.log(`> Ready on http://localhost:${port}`); }); }
-
manifest 작성
/static/manifest.json
{ "name": "Your app name", "short_name": "Your app short_name", "background_color": "#FFFFFF", "theme_color": "status bar color", "description": "Your app description", "display": "standalone", "start_url": "/", "icons": [{ "src": "/static/icon_192.png", "type": "image/png", "sizes": "192x192" },{ "src": "/static/icon_512.png", "type": "image/png", "sizes": "512x512" }] }
-
meta tag 추가
ios를 위한 태그와 manifest 사용을 위한 태그를 넣어줍니다.
<Head> ... <meta name="theme-color" content="status bar color"/> <meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="apple-mobile-web-app-status-bar-style" content="ios status bar color"/> <meta name="apple-mobile-web-app-title" content="Your app title"/> <link rel="apple-touch-icon" href="/static/icon_192.png"/> <link rel="shortcut icon" href="/static/icon_192.png"/> <link rel="manifest" href="/static/manifest.json"/> </Head>
-
service worker 등록
/pages/_app.js
if ('serviceWorker' in navigator) { navigator.serviceWorker .register('/service-worker.js') .then(registration => { console.log('service worker registration successful') }) .catch(err => { console.warn('service worker registration failed', err.message) }) }
-
noscript 태그 추가
/pages/_app.js
<Container> ... <noscript>You should use javascript</noscript> </Container>
위 과정을 다 따르고 서버에 빌드 후 서버를 시작해서 크롬으로 접속해보세요.
chromeDevTools > Audits > Run audits를 실행해보시면 내 웹이 PWA로서 동작할 수 있는지, 앱으로 설치 가능한 상태인지 체크가 가능합니다.
만약 오류가 있다면 해당 오류메세지를 보고 수정하시면 됩니다.
PWA 앱 상태로 인스톨시키기
pwa를 잘 적용하셨다면, 모바일 사용자에게 홈 화면에 인스톨 시킬 수 있습니다.
Android 사용자는 홈페이지에 접속 시에 배너가 노출되어 홈 화면에 앱을 설치할 것인지 물은 후에 홈 화면에 자동으로 앱이 설치됩니다.
IOS 사용자는 배너를 지원하지 않기 때문에 사용자가 직접 홈 화면에 추가 버튼을 눌러서 설치할 수 있습니다.