Nextjs 14 Offline Page with PWA

Mert Enercan
4 min readDec 1, 2023

Time for an exciting update! In this session, we’ll explore the customization of the ‘offline’ page that users see when the application is not connected to the internet. Instead of relying on the default offline page provided by the browser, we’ll leverage the capabilities of a package called next-pwa. What sets this tutorial apart is that, in addition to implementing this package, we’ll delve into the low-level workings of it, gaining a deeper understanding of its mechanics. So, without further ado, let’s dive into the intricacies of this process!

What is PWA

PWA stands for “Progressive Web App.” A Progressive Web App is a type of application software delivered through the web, built using common web technologies such as HTML, CSS, and JavaScript. The key features of PWAs include the ability to work offline, push notifications, and the ability to be installed on a user’s device like a native app. PWAs aim to provide a seamless and engaging user experience across various devices and network conditions. Check out for detailed information: Progressive Web Apps

Next PWA

On a low-level basis, the “next-pwa” package utilizes Service Workers. I’ll not cover Service Workes in this article (cause i barely know about it lol). This foundational technology empowers the seamless integration of Progressive Web App (PWA) functionalities into your Next.js application. The versatility of this package becomes apparent with its extensive range of configuration options for your app. Nevertheless, our primary emphasis in this article will be directed toward the detailed implementation of the “offline” page feature.

Setting Up Our App

First, let’s install our package!

npm i @ducanh2912/next-pwa
pnpm i @ducanh2912/next-pwa
bun add @ducanh2912/next-pwa

You need to create a manifest.json file under the public folder. You can generate this manifest.json from here. (or simply search for manifest.json generator, it’s all the same, i guess.)

"name": "",
"short_name": "",
"theme_color": "#00ff00",
"background_color": "#ffffff",
"display": "browser",
"orientation": "any",
"scope": "/",
"start_url": "/",
"icons": [
"src": "/icons-192.png",
"type": "image/png",
"sizes": "192x192"
"src": "/icons-256.png",
"type": "image/png",
"sizes": "256x256"
} ]

This is an example of how manifest.json file should look like.

After that, for offline page settings, first you need to create a route.
I created “offline” folder in the app router. It looks like this:

└── app/ 
├── offline/
│ └── page.tsx
├── page.tsx
├── layout.tsx
└── favicon.ico

And finally, in the next.config file you need to specify the fallback route:

const withPWA = require("@ducanh2912/next-pwa").default({
cacheOnFrontEndNav: true,
aggressiveFrontEndNavCaching: true,
reloadOnOnline: true,
swcMinify: true,
dest: "public",
fallbacks: {
//image: "/static/images/fallback.png",
document: "/offline", // if you want to fallback to a custom page rather than /_offline
// font: '/static/font/fallback.woff2',
// audio: ...,
// video: ...,
workboxOptions: {
disableDevLogs: true,
// ... other options you like
/** @type {import('next').NextConfig} */
const nextConfig = {
// ... other options you like

module.exports = withPWA(nextConfig);

And thats basically it.

Do not forget, it may not work while in development server, try npm run build and after npm run start if it is not working.

With this configuration, if a user encounters connectivity issues, clicking on another route will trigger the display of the custom offline page instead of the browser’s default “No Connection” page. This enhancement ensures a more seamless and user-friendly experience in case of network disruptions.

How to test it?

Within the developer console, navigate to the “Network” tab, where you’ll find a dropdown menu. Set this menu to “offline” for testing purposes, simulating the conditions that trigger the appearance of your custom offline page. This step allows you to validate and fine-tune the behavior of your offline page in a controlled testing environment.

Also you may see active Service Workers in the “Application” tab.

Here’s an example NextJS app that i covered for this article:

Live Link: 🔗
Repo Link: 🔗

My Website:

Until next time, peace!

Do not forget to drink at least 2L of water/day