본문 바로가기

프론트엔드/Next.js

Next.js에 PWA 적용하기

  • 키워드: next-pwa, PWA, next.js
  • 상황
    1. Google I/O 2022와 2022 Apple WWDC에서 각각 chrome PWA 추가 기능과 Web Push Notification 지원에 관한 발표가 나오면서, 웹의 가능성이 더욱 넓어졌다.
    2. PWA를 프로젝트에서 제대로 사용해본 적은 없지만, 브라우저가 향하고 있는 방향성에 맞게 PWA를 간단하게나마 체험해보고자 한다.
  • 해결 과정
    1. Next.js 프로젝트에서 next-pwa 패키지를 설치한다.
        yarn add next-pwa
    2. next.config.js에서 next-pwa 패키지를 연결한다.
      /** @type {import('next').NextConfig} */
      const withPWA = require('next-pwa');
      
      module.exports = withPWA({
        pwa: {
          dest: 'public',
        },
        ...
      });
    3. 이제 yarn build로 프로젝트를 빌드하면, public 폴더 아래에 workbox-*.js와 sw.js(service worker)가 생성된다.
      sw.js, workbox-*.js
    4. PWA에 필수적인 manifest.json을 생성한다.
      예제는 vegimap 프로젝트에 사용된 manifest.json이다.
        // manifest.json
      {
        "name": "vegimap",
        "short_name": "vegimap",
        "display": "standalone",
        "orientation": "portrait",
        "theme_color": "#FFFFFF",
        "background_color": "#FFFFFF",
        "start_url": "/",
        "icons": [
          {
            "src": "/icons/vegimap-192x192.png",
            "sizes": "192x192",
            "type": "image/png",
            "purpose": "any maskable"
          },
          {
            "src": "/icons/vegimap-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
          }
        ]
      }
      manifest 설정 가이드에 따라, 'short_name', 'start_url', '192x192 pixel과 512x512 pixel size의 icons'을 작성한다.
      (https://web.dev/installable-manifest/#lighthouse)

    5. PWA에 필수적인 meta tag들도 작성한다.
      이 전 포스트(Next.js SEO plugin 이용하기)에서 설명했듯, _document.tsx를 사용하지 않고 있기 때문에 seo.config.js에서 meta/link tag를 작성한다.
        // seo.config.js
      export default {
        ...
        additionalLinkTags: [
          {
            rel: 'shortcut icon',
            href: '/favicon.ico',
          },
          {
            rel: 'manifest',
            href: '/manifest.json',
          },
          // iOS
          {
            rel: 'apple-touch-icon',
            sizes: '180x180',
            href: '/icons/vegimap-180x180.png',
          },
          ...
        ],
        additionalMetaTags: [
          {
            name: 'application-name',
            content: 'vegimap',
          },
          // iOS
          {
            name: 'apple-mobile-web-app-title',
            content: 'vegimap',
          },
          {
            name: 'apple-mobile-web-app-capable',
            content: 'yes',
          },
          {
            name: 'apple-mobile-web-app-status-bar-style',
            content: 'default',
          },
          {
            name: 'format-detection',
            content: 'telephone:no',
          },
          // Android
          {
            name: 'mobile-web-app-capable',
            content: 'yes',
          },
          {
            name: 'theme-color',
            content: '#FFFFFF',
          },
          ...
        ],
      };


    6. 이제 프로젝트를 build하고 start하면, 크롬 브라우저 주소창 오른쪽에 '설치 아이콘'이 생긴다.
      앱 설치 아이콘 생성

      혹시 localhost에 해당하는 service worker를 unregister 해두었다면 설치 아이콘이 생기지 않을텐데(ERROR: no matching service worker detected),
      아래의 코드를 실행시켜 수동으로 service worker를 재등록하여 해결한다.
        useEffect(() => {
        require('next-pwa/register');
      }, []);

      사이트 배포 후, 안드로이드 삼성인터넷 웹사이트를 접속해도 마찬가지로 아이콘이 생성되며 설치도 가능하다.
      안드로이드 삼성인터넷 PWA

      PWA는 대부분의 modern browser에서 지원한다.
      (https://web.dev/learn/pwa/progressive-web-apps/#compatibility)
      다만 데스크톱의 safari, firefox는 지원하지 않고 있고, iOS일 경우 safari 브라우저를 사용해야만한다.
      휴대폰에 PWA 앱이 설치된 모습
    7. 간단한 설정을 통해 Next.js 프로젝트를 PWA로 만들고 휴대폰에서 설치해보았다.
      아직 앱에 비해 많은 제약사항이 있지만(특히 iOS 쪽에서...) 구글이 PWA를 강하게 밀고 있고, 애플도 이번 WWDC를 통해 훨씬 더 열린 자세를 보여주었으니 웹과 PWA의 발전을 기대해봐도 좋을 것 같다!

 

20221210 추가

- Next 13 beta version에서 manifest.json 404 error가 발생하면 아래의 코드를 next-pwa config에 추가한다.

buildExcludes: [/app-build-manifest.json$/],