Building A PWA With NextJS 12 and Typescript
Tags: pwa, nextjspwa, nextjs, pwatypescript
Published: 2022-05-23 10:46:10

## Intro <a href="#intro"></a>

Hello GUYS!!

Are you tired of building the same app thing twice or even more? What if I tell and so you one way that can help you save time and a lot of effort? So let me introduce to you a way that can help you saving time time sometimes. So what I'm gonna introduce to you is a way of creating [**PWA**](https://web.dev/progressive-web-apps/) with [**Next JS**](https://nextjs.org/).

## Table of contents
 - [Intro](#intro)
 - [What's a PWA?](#section-1)
 - [What we're building?](#section-2)
 - [Our Arsenal](#section-3)
 - [The Application](#section-4)
 - [ Making The Application PWA](#section-5)
 - [Congratulations](#section-6)
 - [References](#section-7)
 - [The project](#the-project)
 - [See Demo](#demo)

## What's a PWA? <a name="section-1"></a>

According to [Developer Mozilla](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps), **PWAs**(Progressive Web Apps) are web apps that use service workers, manifests, and other web-platform features in combination with progressive enhancement to give users an experience on par with native apps.

**And what this means?** This means that you can make your web apps work like a native app (no matter what platform you will use, windows, mac OS, android, IOS,...), you will be able to write once and make you web app _installable_ making your app browser independent.

Checkout for more details about PWA: [_web.dev_](https://web.dev/progressive-web-apps/), [Developer Mozilla](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)

## What we're building? <a name="section-2"></a>
We'll build an **Countdown App**, that notifies the user in every _two hours_, to help us stand up and fight against the sedentary.

## Our Arsenal <a name="section-3"></a>

Since the goal is to build a Next JS app, it's mandatory to know the basics of [React jS](https://reactjs.org/).

To bring this idea to life we'll use the following tools: [**Next JS**](https://nextjs.org/), [**TypeScript**](https://www.typescriptlang.org/) and [**Mantine UI**](https://mantine.dev/).

**TypesScript** is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.

**Mantine UI** is a fully featured react component library.

## The Application <a name="section-4"></a>

**If** you already have your app done and you just want make it a PWA app, you can jump into [**Making The Application PWA**](#section-5) section.

**Else** let's star by cloning 
```
git clone https://github.com/Dalcio/sedentarism-alert

cd sedentarism-alert
```
``` 
yarn install && yarn run dev 
``` 
or
``` 
npm install && npm run dev 
```

### Sedentarism App Alert


![Sedentarism App alert](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5jwy7mxnt7gyd64j8sm.PNG)

Now that we have our project settled, let's jump into and take a quick look at our project structure:

![Project Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbczulyt961qr9u7vatz.PNG)

- **public/*** we have two files, our logo and the sound that's played when the times end.

- **src/styles** contains a simple component at **src/styles/global** that contains a couple of global styles.

- **src/pages** responsible to contain our pages, we have only one page (the Home page).

- **src/components** contains the body of our countdown.

- **src/hooks** contains our custom hooks **useCounter** responsible to handle the time and **usePlaySound** responsible to handle the audio played when the clock is zero.


So, now that we understand our project let make our tiny app PWA.

## Making The Application PWA <a name="section-5"></a>

Now that we have an app [(if don't)](#section-4), it's time to make our app PWA.

First I'll resize the icons 4x because of the the different screen that exist.

### Steps

To make our app pwa we need to do the following steps:
- [install next-pwa dependency](#step-one)
- [configure PWA in Next Config](#step-two)
- [generate the manifest](#step-three)
- [add the manifest in _document.tsx](#step-four)

#### Installing Next PWA dependency <a href="#step-one"></a>

We have to install [**next-pwa**](https://www.npmjs.com/package/next-pwa)

```
yarn add next-pwa
```
or
```
npm i next-pwa 
```

#### Configuring Next Config <a href="step-two"></a>

Now we need to configure our `next.config.js` to look the following:

````js
/** @type {import('next').NextConfig} */
const withPWA = require('next-pwa');

const nextConfig = withPWA({
  pwa: {
    dest: 'public',
    register: true,
    skipWaiting: true,
  },
  reactStrictMode: true,
});

module.exports = nextConfig;

```

#### Generating the manifest <a href="step-three"></a>

There's many option available that can help you generate the **manifest**, I'll just use [simicart](https://www.simicart.com/manifest-generator.html/)
and fill the form.

![Manifest Generator field](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tptarks0qqyz0l85cmui.PNG)

and click on generate and upload the files generated to your public folder. After all rename the `manifest.webmanifest` to `manifest.json`

The generated JSON file
````json
{
    "theme_color": "#247ED6",
    "background_color": "#77eed8",
    "display": "standalone",
    "scope": "/",
    "start_url": "/",
    "name": "Sedentarism Alert",
    "short_name": "SAlert",
    "description": "It's an app that plays a sound when the time is 0 ",
    "icons": [
        {
            "src": "/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "/icon-256x256.png",
            "sizes": "256x256",
            "type": "image/png"
        },
        {
            "src": "/icon-384x384.png",
            "sizes": "384x384",
            "type": "image/png"
        },
        {
            "src": "/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}
```

#### Add the manifest in _document.tsx <a href="step-four"></a>

Now we'll configure the manifest in our `_document.tsx` file, looking like:

```tsx
import { createGetInitialProps } from '@mantine/next';
import Document, { Head, Html, Main, NextScript } from 'next/document';

const getInitialProps = createGetInitialProps();

export default class _Document extends Document {
  static getInitialProps = getInitialProps;

  render() {
    return (
      <Html>
        <Head>
          <title>Sedentarism Alert - PWA</title>
          <link
            rel="shortcut icon"
            href="alarm-clock.png"
            type="image/x-icon"
          />
          <link rel="manifest" href="/manifest.json" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

```

## Congratulations <a name="section-6"></a>

Now our app is a PWA. Congratulation. Now you can deploy it on [**Vercel?»*](https://vercel.com/guides/deploying-nextjs-with-vercel)

## References <a name="section-7"></a>
[Progressive web apps (PWAs)](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)
[Progressive Web Apps](https://web.dev/progressive-web-apps/?gclid=CjwKCAjw4ayUBhA4EiwATWyBrvb4n5SU8fTzo774tAXUQ8CgYo-bT1z2-EeUXuMtvN_yCvQOm6JE-BoC-nAQAvD_BwE)
[How to Create a PWA With Next.js in 10 Minutes](https://www.youtube.com/watch?v=ARNN_zmrwcw)
[How to make a Next.js app a PWA](https://medium.com/geekculture/how-to-make-a-next-js-app-a-pwa-a5e2b13da548)

## The Project <a name="the-project"></a>

### [**Project Repository**](https://github.com/Dalcio/sedentarism-alert)

## See Demo <a name="demo"></a>

### [Live Demo](https://sedentarism-alert.vercel.app/)