2020/06/03

Vue CLIで作ったPWAがNetlifyでリダイレクトされない

PWAをNetlifyにデプロイしたときに、リダイレクトされない問題を解決しました。

Netlify でリダイレクトされない

Vue-cli と vue/cli-plugin-pwa で作った Web アプリを Netlify でホストしていて、public/redirectsファイルは以下のようになっています。1行目の index.html にリダイレクトさせる動作は正しく動いているのですが、2行目の netlify.app ドメインをカスタムドメインにリダイレクトする動作が動いていない状態です。

/*    /index.html   200
https://your-app.netlify.app/* https://yourapp.com/ 301!

Netlify のコミュニティに同じような問題が報告されていました。

Redirect from Netlify subdomain to custom primary domain not working

curl でアクセスしたところ、301 が帰ってきているようですが、ブラウザではリダイレクトされないという状況です。 ServiceWorker あたりの問題らしいですが、最終的には Javascript でリダイレクトして解決しました。

最初に読み込まれるindex.htmlのヘッダ内に netlify のサブドメインのとき、オリジナルドメインにリダイレクトさせる処理を追加しました。 ヘッダ内のスクリプトなので、ページ読み込み時に一番最初に実行されるため、速度的には問題ないかと思います。

<head>
  <title>title</title>
  <script>
    if (location.host === "subdomain.netlify.app") {
      location.href = "https://original-domain.com";
    }
  </script>
</head>

_redirects を ServiceWorker のキャッシュを除外する

この問題を調べているときに、ブラウザのコンソールを見てみると_redirectが見つかりませんでしたというようなエラーが出ています。上のリダイレクトとは直接関係ないですが、エラーなので解決しておきました。

PrecacheController.mjs:194 Uncaught (in promise) bad-precaching-response: bad-precaching-response

これは、public 内にあるファイルを ServiceWorker を制御するライブラリである Workbox が自動的にキャッシュする設定になっているためです。しかし、_redirectsファイルは Netlify の設定のために置いてあるのであって、実際にhttps://domain.com/_redirectsのようにアクセスすると 404 になります。

そこで、vue.config.jsの設定で以下のように_redirectsファイルのキャッシュを除外できます。

module.exports = {
  pwa: {
    workboxOptions: {
      exclude: [/_redirects/],
    },
  },
};