# Progressive Web Apps (PWA)

## Overview

[PWA](https://web.dev/progressive-web-apps/) stands for Progressive Web App. It is a type of web application that combines the capabilities of a native mobile app with the accessibility of a website. PWAs can be accessed through a web browser, but they can also be installed on a user's device and launched from their home screen, just like a native app.

## How to use

Here we use PWA. The installation method is as follows below.

{% hint style="info" %}
[The official PWA documentation](https://www.npmjs.com/package/next-pwa)
{% endhint %}

### Step 1: Install the next-pwa package

You need to install the `next-pwa` package, which is a Next.js plugin that helps you to easily add PWA support to your app. Run the following command in your terminal to install it:

```bash
yarn add next-pwa next-offline
```

### Step 2: Configure the PWA

Now, you need to configure the PWA by adding a `next.config.js` file to the root of your app directory with the following code:

```typescript
const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    dest: 'public',
    disable: process.env.NODE_ENV === 'development'
  }
})
```

This code sets up the `next-pwa` plugin and configures the PWA options. The `dest` option specifies the directory where the PWA assets will be generated, and the `disable` option disables the PWA in development mode.

### Step 3: Add PWA assets

Next, you need to add the PWA assets to your app. Create a `public` directory in the root of your app directory if it doesn't exist yet, and add the following files to it:

* `manifest.json`: A JSON file that describes your app and its PWA properties. Here is an example:

```json
{
  "name": "My App",
  "short_name": "My App",
  "start_url": "/",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "icons": [
    {
      "src": "/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ]
}
```

* `icons/icon-192x192.png`: A 192x192 pixel PNG icon for the PWA.
* `icons/icon-512x512.png`: A 512x512 pixel PNG icon for the PWA.

### Step 4: Register the PWA service worker

Finally, you need to register the PWA service worker in your app. To do this, add the following code to your `_app.tsx` file:

```tsx
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { register, unregister } from 'next-offline/runtime'

function MyApp({ Component, pageProps }: AppProps) {
  const router = useRouter()

  useEffect(() => {
    if ('serviceWorker' in navigator) {
      const handleRouteChange = () => {
        unregister()
      }

      router.events.on('routeChangeStart', handleRouteChange)

      register('/service-worker.js', {
        onUpdate: () => {
          const event = new Event('sw.update')
          window.dispatchEvent(event)
        },
        onOfflineReady: () => {
          const event = new Event('sw.offlineReady')
          window.dispatchEvent(event)
        },
      })

     
      return () => {
        router.events.off('routeChangeStart', handleRouteChange)
      }
    }
  }, [])

  return <Component {...pageProps} />
}

export default MyApp
```

This code registers the service worker using the `next-offline` package, which is a plugin for Next.js that provides offline support for your app. The `register` function takes two arguments: the path to the service worker file (`/service-worker.js` in this case), and an options object that specifies what to do when the service worker updates or becomes ready offline.

The `useEffect` hook ensures that the service worker is only registered once, when the app mounts. The `router.events` object listens for changes to the URL and unregisters the service worker when the user navigates away from the app.
