Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.js PWA (Service Worker + Manifest.json)

I am using Next.js to develop a Server Side Rendering website and I want to make it a Progressive Web App but the problem I couldn't find the way to make it happen correctly.

When I build the application it serves correctly the service worker but there is no manifest.json and in some projects examples it serves the manifest.json but I tried it in Lighthouse audit and it says

Service worker does not successfully serve the manifest's start_url

One of the examples I used Create Next App With Service Worker Precache

I think that the problem is that the start_url is . or / and not a valid file because in Next.js there is no index.html to serve from the start.

In summary I am looking for an example using Next.js to build it to a dist folder and when I serve it it has a valid Service Worker and a valid Web Manifest.

like image 767
Sofienne Lassoued Avatar asked Jul 31 '18 17:07

Sofienne Lassoued


People also ask

What is PWA manifest JSON?

The web app manifest is a JSON file that defines how the PWA should be treated as an installed application, including the look and feel and basic behavior within the operating system.

Is next JS good for PWA?

js Progressive Web App (PWA)? Yes!

How do I add a manifest file to Nextjs?

Add manifest.Link your manifest. json file to your Nextjs app head tag. Now if you go to Devtools then clicking on the Application tab and then Manifest tab you can see all the fields are now generated, which shows that our manifest.


1 Answers

A. Some file are expected to be found at "/"

You have this error because browsers expect some files to be served from the root of the server, including:

  1. /manifest.json
  2. /sitemap.xml
  3. /favicon.ico
  4. /robots.txt
  5. /browserconfig.xml
  6. /site.webmanifest

While the majority of these paths can be set with meta tags, older browsers just ignore them and error if these exact file names are not served.

B. Configure alternative paths and use NextJS static file

At the time of writing, there is ongoing work for supporting offline in NextJS. But it's not ready yet.

If you don't need to support older browsers and you don't want advanced SEO, you can use NextJS's Head component (see documentation) to define the manifest.json path like you would for any NextJS static file:

import Head from "next/head"

export default () => (
    <Head>
        <link rel="manifest" href="/static/manifest.json" />
        <link rel="manifest" href="/static/site.webmanifest" />
        <link rel="shortcut icon" href="/static/favicon.ico"
    </Head>
)

Please note that robots.txt cannot be serve from a subdirectory (source), so this solution is not a good fit if you need to define this file.

C. Serve these files like expected

The proper solution would be to serve these files from your express server like so

const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const { join } = require('path')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare()
  .then(() => {
    createServer((req, res) => {
      const parsedUrl = parse(req.url, true)
      const rootStaticFiles = [
        '/manifest.json',
        '/sitemap.xml',
        '/favicon.ico',
        '/robots.txt',
        '/browserconfig.xml',
        '/site.webmanifest',
      ]
      if (rootStaticFiles.indexOf(parsedUrl.pathname) > -1) {
        const path = join(__dirname, 'static', parsedUrl.pathname)
        app.serveStatic(req, res, path)
      } else {
        handle(req, res, parsedUrl)
      }
    })
      .listen(port, (err) => {
        if (err) throw err
        console.log(`> Ready on http://localhost:${port}`)
      })
  })

Note: This code directly comes from the NextJS examples repository

like image 191
Clément Prévost Avatar answered Oct 14 '22 23:10

Clément Prévost