pwa-installをReact(Nextjs)で使う

pwa-installというWeb Componentを使うことで、manifest.jsonのデータを元にアプリのインストール画面を作ることができます。

yarn add @pwabuilder/pwa-install

これをReactアプリ、特にNext.jsやGatsbyなどのSSR処理が入るもので使う場合の覚書です。

SSR / SSGでの注意点

Web Component系をReactで使う時、かなりの確率でNodejs側の処理がこけます。これはwindow系のオブジェクトを使用しようとするWeb Component側の動きがNodejsではwindow is undefinedになることが原因です。

node_modules/@pwabuilder/pwainstall/dist/pwa-install.js:172
 (window.litElementVersions||(window.litElementVersions=[])).push("2.3.1");const Q={};class X extends W{static getStyles(){return this.styles}static _getUniqueStyles(){if(this.hasOwnProperty(JSCompiler_renameProperty("_styles",this)))return;const t=this.getStyles();if(void 0===t)this._styles=[];else if(Array.isArray(t)){const e=(t,i)=>t.reduceRight((t,i)=>Array.isArray(i)?e(i,t):(t.add(i),t),i),i=e(t,new Set),n=[];i.forEach(t=>n.unshift(t)),this._styles=n}else this._styles=[t]}initialize(){super.initialize(),this.constructor._getUniqueStyles(),this.renderRoot=this.createRenderRoot(),window.ShadowRoot&&this.renderRoot instanceof window.ShadowRoot&&this.adoptStyles()}createRenderRoot(){return this.attachShadow({mode:"open"})}adoptStyles(){const t=this.constructor._styles;0!==t.length&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow?Y?this.renderRoot.adoptedStyleSheets=t.map(t=>t.styleS
 SyntaxError: Unexpected token 'export'

pwa-installをReactで使う

上記の問題があるため、pwa-installの読み込みはuseEffectを使った副作用で行います。

import React, {FC, useEffect} from 'react'

export const PWAInstall: FC = () => {
    useEffect(() => {
        import("@pwabuilder/pwainstall")
            .then(data => {
                const target = document.getElementById('pwa-install-root')
                const installComponent = document.createElement("pwa-install")
                target.appendChild(installComponent);
                (installComponent as any).getInstalledStatus();
            })
            return
    },[])
    return (
        <div id="pwa-install-root"/>
    )
}

ボタンなどをカスタマイズしたい場合は、setAttributeを使いましょう。

                const installComponent = document.createElement("pwa-install")
                installComponent.setAttribute(
                    'installbuttontext', 'Install applcaition'
                );
                target.appendChild(installComponent);

manifest.jsonに機能系のデータを足す

pwa-installで表示されるインストール画面には、「Features」という項目があります。ここには、manifest.jsonfeatures属性が利用されます。この属性はpwa-installが独自に使うモノの様子ですので、他にPWA系のツールを使われている場合などではコンフリクトしないかのチェックは行いましょう。

{
    "name": "WP Kyoto",
    "short_name": "WP Kyoto",
...
    "description": "WP Kyotoのブログサイトです。 Alexa / Serverless(AWS) / Reactなどについての記事をメインに更新しています。",
    "features": [
      "Blog",
      "Search Post",
      "Experimental"
    ]
  }

PWA Install非対応デバイスでは動かないので要注意

このWeb Component、installできないと判断されたデバイスのブラウザでは要素がそもそも表示されません。

そのため、動作テストしたい場合は、開発ツールなどでDeviceのUAを変えてやりましょう。

Comment