DEV Community

Cover image for PWA with Next Js 13
Sabbir Zzaman
Sabbir Zzaman

Posted on

PWA with Next Js 13

What is PWA?

Progressive Web Applications (PWAs) are apps built with web technologies that we probably all know and love, like HTML, CSS, and JavaScript. But they have the feel and functionality of an actual native app.

Before we have to manage different code bases for web, android, and ios applications. But PWA makes developers life easy. Now we can manage all those with a single code base. We can turn any websites or web apps into a installable mobile application and use it in different platforms.

Benefits of PWA

  1. Have Cross-platform compatibility.
  2. They're fast and lightweight.
  3. They work offline unlike other sites.
  4. Push notifications functionality.
  5. Low maintenance cost.

Example of a PWA

Twitter is a great example of a PWA, with its fast loading times, responsive design, and ability to function offline. The PWA version of Twitter can be accessed at the URL https://twitter.com/, and it allows users to browse and interact with tweets in a mobile-friendly and app-like interface. The Twitter PWA also supports push notifications, enabling users to receive updates and alerts in real-time. The PWA is designed to be accessible and optimized for all devices, including desktop and mobile, making it easy for users to stay connected and engage with their followers on the go.

What you're going to learn?

  1. You can create a PWA with Next Js from startch.
  2. You can convert your existing app with a PWA.

Next Js PWA Boilerplate

If you're more of a code-first kind of person, you can find a ready-to-go boilerplate here. However, I still recommend reading the rest of this post to gain a better understanding of how everything works together.

GitHub - sabbirzzaman/next-pwa

Or just run this command to clone the repository in the terminal. (TypeScript)



https://github.com/sabbirzzaman/next-pwa.git


Enter fullscreen mode Exit fullscreen mode

For JavaScript



git clone -b with-js https://github.com/sabbirzzaman/next-pwa.git


Enter fullscreen mode Exit fullscreen mode

Let's create a PWA

First open your terminal and create a Next Js project.



npx create-next-app@latest


Enter fullscreen mode Exit fullscreen mode

Generate Manifest file

A manifest file is a JSON file that provides metadata and configuration details about a PWA. It contains information such as the app's name, icons, start URL, theme color, and display mode. The manifest file is used by web browsers to identify and install the PWA, allowing it to behave more like a native app on the user's device. The manifest file is also used by the browser to display the PWA's name, icon, and splash screen when the app is launched.

You can simply create a manifest.json file in the public folder and copy the below manifest and modify the name, colors, description, etc as par your requiremts. Or you can also generate a new one for you from this website: simicart



{
  "theme_color": "#3b82f6",
  "background_color": "#f8fafc",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "name": "Your App Name",
  "short_name": "your_app_name",
  "description": "A PWA boilerplate with Next Js TypeScript",
  "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"
    }
  ]
}


Enter fullscreen mode Exit fullscreen mode

This is how the public folder will look like after creating the manifest.json file.
Image description

Create _document file

Next you have to create a _document.js, _document.jsx or _document.tsx file the in the pages directory and paste the following code.



import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html lang="en">
      <Head>
        <link rel="manifest" href="/manifest.json" />
        <link rel="apple-touch-icon" href="/icon.png"></link>
        <meta name="theme-color" content="#fff" />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}


Enter fullscreen mode Exit fullscreen mode

The _document.tsx file in Next.js is used to customize the HTML document served to the user's browser, allowing developers to add custom HTML head elements and modify the HTML structure of the page. It is executed only on the server-side during the initial rendering of the page and is commonly used to add server-side rendering support for CSS-in-JS libraries or to add global styles and scripts to the page.

Next PWA Configuration

In Next.js, developers can configure their project using the default configuration file, next.config.js. Simply open the file and paste the following code.

Note: if your project is not in TypeScript you can ingore the /** @type {import('next').NextConfig} */ line.



/** @type {import('next').NextConfig} */

const withPWA = require('next-pwa')({
  dest: 'public',
  register: true,
  skipWaiting: true,
});

module.exports = withPWA({
  reactStrictMode: true,
});


Enter fullscreen mode Exit fullscreen mode

Some gitignores

After creating the build, you will see several auto generated .js files in your public folder. You don't need to keep those in GitHub. For ignoring those you can can paste those following lines in your .gitingore file.



# Auto Generated PWA files
**/public/sw.js
**/public/workbox-*.js
**/public/worker-*.js
**/public/sw.js.map
**/public/workbox-*.js.map
**/public/worker-*.js.map


Enter fullscreen mode Exit fullscreen mode

Local build and test the PWA

After completing the configuration process, you can test your Next.js application. To test the PWA locally, you need to create a new build. Stop the terminal and use the following command to create a build:



npm run build


Enter fullscreen mode Exit fullscreen mode

Now that you have created a new build, you can run it locally.



npm run start


Enter fullscreen mode Exit fullscreen mode

Alright, so now that you've created a fresh build, let's test it out on your local machine! Head over to http://localhost:3000 in your favorite browser and keep an eye out for the installable icon located in the right corner of the URL box. Click on that bad boy and you should be able to search for the app on your computer and run it like a pro!

That's it, folks! Now you know how to turn your Next.js website into a fancy PWA app. Cheers!

Top comments (16)

Collapse
 
3delton profile image
3DElton

created an account on this platform just to say Thank You

Collapse
 
sabbir_zz profile image
Sabbir Zzaman

@3delton I'm so glad to hear that! Thank you for taking the time to create an account and share your appreciation.

Collapse
 
ffan0811 profile image
MJ

Thanks a lot for the good post!

I have one question. According to the official document, the manifest.json should be in the root of app directory. but I keep failing to next build because of the file. so I want to try your method but before that, whats the difference between your method and the official document?

Collapse
 
sabbir_zz profile image
Sabbir Zzaman

@ffan0811

  1. If you put the manifest.js file in the root of your app directory, you would need to set up your server to properly serve this file. This might involve configuring your server or using a server-side framework like Express.js in Node.js.
  2. If you put the manifest.js file in the public folder, it will be served as a static file. In Next.js, any file inside the public directory is mapped to the root URL (/), so public/manifest.js would be accessible at http://localhost:3000/manifest.js. This is the simpler method and is generally recommended for static assets like the manifest file.

In the context of a PWA, the manifest.js file needs to be accessible from the client-side, so it's typically placed in the public directory. This way, it can be easily linked in the HTML document's head section like so: <link rel="manifest" href="/manifest.js">.

Collapse
 
wynstelleid profile image
WynstelleID

thanks bro, it works for me!

Collapse
 
ramdhanstdi profile image
Ramdhan Setiadhi

yo bro thanks, but i want to ask something
this set up can provide offline mode? like moving to other page

Collapse
 
sabbir_zz profile image
Sabbir Zzaman

@ramdhanstdi yeah, we can switch pages in offline mode. But API can't fetch on offline mode for sure. You should display an error message for that.

Collapse
 
flyingwolf1701 profile image
Patrick Reid

This is the think I hate about this package. They don't want to think in terms of offline-first, but it is literally the only way to do a PWA in Next.js

There is a package called next-offline but it hasn't been maintained in ages. I have to write something up if I actually figure this offline-first problem out. but right now it is frustrating.

Collapse
 
biggerwad profile image
Daniel wesey

Thank you! @sabbir_zz

Collapse
 
arashcoder profile image
Arash Barghash

I did all above steps, It works well on my system but when I push my code to the server for production , the project get 500 internal error. where is the problem ???

Collapse
 
sabbir_zz profile image
Sabbir Zzaman

@arashcoder I think it's a deployment issue. Can you make sure you are deploying the project in a right way?

Collapse
 
arashcoder profile image
Arash Barghash

Bro I had a mistake thats was not related to the pwa at all . I was using β€œsharp” package for optimizing my images on production and that caused error 500 on the production . I removed the package and everything work as expected

Thank you for you r good documentation:)

Collapse
 
andreyscott profile image
Andreyscott

it didn't work for me there was no service worker file or any other created with npm run build (in my case yarn run build)

Collapse
 
felixselter profile image
FelixSelter

Did you install next-pwa?

Collapse
 
salmanshahriar profile image
Salman Shahriar

Thank you for the excellent post!

Collapse
 
jyoung4242 profile image
Justin Young

any suggestions for controlling splash screen? looking for resources on this...