web-dev-qa-db-ja.com

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

Next.jsを使用してサーバーサイドレンダリングのWebサイトを開発しています。それをプログレッシブWebアプリにしたいのですが、問題を正しく実行する方法が見つかりませんでした。

アプリケーションをビルドすると、Service Workerは正しく機能しますが、manifest.jsonがありません。一部のプロジェクトの例では、manifest.jsonを提供しますが、Lighthouse監査で試してみました。

Service Workerがマニフェストのstart_urlを正常に提供していません

私が使用した例の1つ Service Worker Precacheで次のアプリを作成

問題は、start_urlがであることにあると思います。または/および有効なファイルではありません。Next.jsには最初から提供するindex.htmlがないためです。

要約すると、私はNext.jsを使用してdistフォルダーにビルドする例を探しています。これを提供すると、有効なサービスワーカーと有効なWebマニフェストが含まれます。

5

A.一部のファイルは "/"にあると予想されます

ブラウザは、次のようなファイルがサーバーのルートから提供されることを想定しているため、このエラーが発生します。

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

これらのパスの大部分はメタタグを使用して設定できますが、古いブラウザはこれらのパスを無視し、これらの正確なファイル名が提供されない場合はエラーになります。

B.代替パスを構成し、NextJS静的ファイルを使用する

執筆時点では、NextJSには オフラインをサポートするための作業中 があります。しかし、まだ準備ができていません。

古いブラウザをサポートする必要がなく、高度なSEOも必要ない場合は、NextJSのHeadコンポーネント( ドキュメントを参照 )を使用して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.これらのファイルを期待どおりに提供する

適切な解決策は、これらのファイルをExpressサーバーから提供することです

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

:このコードは NextJSサンプルリポジトリ から直接取得されます

9