Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.

Follow publication

Activating PWA in Next.js 13+ App Directory Using @Serwist — Simple Guide

--

Activating PWA in Next.js 13+ App Directory Using @Serwist — Simple Guide

Introduction:

PWA or Progressive Web App is a web application that uses modern web capabilities to deliver a more native app-like experience to users. PWAs aim to combine the best of web and native apps.

This guide will show how we can make our Next.js with AppDir a PWA!

I have discussed how to make your Next.js App PWA using @ducanh2912/next-pwa , but this guide will focus on @serwist , which is a more recommended way for Next.js. If you want to read about @ducanh2912/next-pwa you can check out the following article:

Benefits of PWA:

There are a lot of benefits to using PWA and some of them are:

  1. Offline Access.
  2. App-Like.
  3. Push Notifications.
  4. Discoverable.
  5. Installable.
  6. Automatic Updates.

and many more…

Companies Using PWA:

To mention some of the companies that are using PWA:

  1. AliExpress
  2. Twitter Lite
  3. Forbes

and much more… Source

Adding PWA support to Next.js:

Step 1 — Create the Next.js App:

To create a new Next.js Project run the following command:

npx create-next-app@latest

Choose the prompts accordingly:

What is your project named? next-with-pwa
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like to use `src/` directory? Yes
Would you like to use App Router? (recommended) Yes
Would you like to customize the default import alias (@/*)? No

If you already have a Next project go to the next step.

Step 2 — Add the Required Package:

Now install the following package:

npm i @serwist/next @serwist/precaching @serwist/sw

Step 3 — Configure the Package:

With the latest next.js, we get next.config.mjs , which would be configured as follows:

// @ts-check
import withSerwistInit from "@serwist/next";

const withSerwist = withSerwistInit({
cacheOnFrontEndNav: true,
swSrc: "src/sw.ts", // add the path where you create sw.ts
swDest: "public/sw.js",
reloadOnOnline: true,
disable: process.env.NODE_ENV === "development", // to disable pwa in development
// ... other options
});

/** @type {import('next').NextConfig} */
const nextConfig = {
swcMinify: true,
reactStrictMode: true,
// ... other next.js config options
};

export default withSerwist(nextConfig);

If you have next.config.js , the configuration would be as follows:

const withSerwist = require("@serwist/next").default({
cacheOnFrontEndNav: true,
swSrc: "src/sw.ts", // add the path where you create sw.ts
swDest: "public/sw.js",
reloadOnOnline: true,
disable: process.env.NODE_ENV === "development", // to disable pwa in development
// ... other options
});

/** @type {import('next').NextConfig} */
const nextConfig = {
swcMinify: true,
reactStrictMode: true,
// ... other next.js config options
};

export default withSerwist(nextConfig);

If you are using TypeScript, update the tsconfig.json as follows:

{
// Other stuff...
"compilerOptions": {
// Other options...
"types": [
// Other types...
// This allows Serwist to type `window.serwist`.
"@serwist/next/typings"
],
"lib": [
// Other libs...
// Add this! Doing so adds WebWorker and ServiceWorker types to the global.
"webworker"
],
},
}

For more options, visit the official documentation here:

Step 4 — Add a Service Worker Configuration:

Add the following configuration at src of your project in a file sw.ts:

// sw.ts

import { defaultCache } from "@serwist/next/browser";
import type { PrecacheEntry } from "@serwist/precaching";
import { installSerwist } from "@serwist/sw";

declare const self: ServiceWorkerGlobalScope & {
// Change this attribute's name to your `injectionPoint`.
__SW_MANIFEST: (PrecacheEntry | string)[] | undefined;
};

// Anything random.
const revision = crypto.randomUUID();

installSerwist({
precacheEntries: self.__SW_MANIFEST,
skipWaiting: true,
clientsClaim: true,
navigationPreload: true,
runtimeCaching: defaultCache,
fallbacks: {
entries: [
{
url: "/~offline",
revision,
matcher({ request }) {
return request.destination === "document";
},
},
],
},
});

Step 5— Add a Fallback Page to be Shown When User is Offline:

Place the ~offline/page.tsx in /app folder and then add the following code to show as a fallback.

import type { Metadata } from "next";

export const metadata: Metadata = {
title: "Offline",
};

export default function Page() {
return (
<>
<h1>This is offline fallback page</h1>
<h2>When offline, any page route will fallback to this page</h2>
</>
);
}

Step 6— Add manifest.json to your app:

Go to public folder of your app and create manifest.json with the following structure:

{
"id": "any_id",
"name": "Next.js PWA - Tutorial",
"short_name": "Next PWA",
"description": "This next.js app is a PWA.",
"icons": [
{
"src": "./logo72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "./logo192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./logo384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "./logo512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#FFFFFF",
"background_color": "#FFFFFF",
"start_url": "/",
"scope": ".",
"display": "standalone",
"orientation": "portrait"
}

Step 6— Registering manifest.json in Metadata:

Update your layout.tsx/layout.jsx to register the manifest file in the metadata:

import { Metadata } from "next";
// ... other imports

export const metadata: Metadata = {
manifest: "/manifest.json", // we are accessing our manifest file here
title: "...",
// ... other options
};

const RootLayout = ({ children }: { children: React.ReactNode }) => {
return (
<html lang="en">
<body>
<main>{children}</main>
</body>
</html>
);
};

export default RootLayout;

And that’s it, Happy Coding! 😊

Access the Code at:

Visit the Live version at: https://next-pwa-serwist.vercel.app/

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Published in Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.

Written by Farasat Ali

Tech Savvy 💖 Blockchain, Web & Artificial Intelligence. Love to travel, explore culture & watch anime. Visit My Portfolio 👇 https://linktr.ee/faraasat

No responses yet

Write a response