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

问题描述 投票:3回答:1

我正在使用Next.js开发一个服务器端渲染网站,我想让它成为一个渐进式Web应用程序,但问题是我无法找到使其正确发生的方法。

当我构建应用程序时,它正确地服务于服务工作者,但是没有manifest.json,并且在一些项目示例中它提供了manifest.json,但我在Lighthouse审计中尝试了它,它说

服务工作者未成功提供清单的start_url

我使用Create Next App With Service Worker Precache的一个例子

我认为问题在于start_url是。或/和不是有效的文件,因为在Next.js中没有index.html从一开始就提供服务。

总而言之,我正在寻找一个使用Next.js将其构建到dist文件夹的示例,当我提供它时,它有一个有效的Service Worker和一个有效的Web Manifest。

manifest service-worker progressive-web-apps next.js lighthouse
1个回答
5
投票

答:有些文件应该在“/”找到

您有此错误,因为浏览器希望从服务器的根目录提供一些文件,包括:

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

虽然可以使用元标记设置大多数这些路径,但旧版浏览器会忽略它们,如果未提供这些确切的文件名则会出错。

B.配置备用路径并使用NextJS静态文件

在撰写本文时,NextJS中有ongoing work for supporting offline。但还没有准备好。

如果您不需要支持旧版浏览器并且您不需要高级搜索引擎优化,则可以使用NextJS的Head组件(see documentation)来定义manifest.json路径,就像您对任何NextJS静态文件一样:

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>
)

请注意,robots.txt不能从子目录(source)提供,因此如果您需要定义此文件,此解决方案不适合。

C.像预期的那样提供这些文件

正确的解决方案是从您的快速服务器提供这些文件

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}`)
      })
  })

注意:此代码直接来自the NextJS examples repository

© www.soinside.com 2019 - 2024. All rights reserved.