PWA Laravel

Got this basic working PWA laravel with serviceworker, manifest...

  • Tried it offline when web finish loaded then turned off webserver and it still on...
  • Tried using ngrok with https add to homescreen works

Create Project Laravel

laravel new Pwa

get all dependencies

npm install

add another

npm install --save-dev sw-precache-webpack-plugin

copy webpack.config.js

update package.json

--config=node_modules/laravel-mix/setup/webpack.config.js
to
--config=webpack.config.js

in webpack.config.js
below let WebpackConfig = require('../src/builder/WebpackConfig');

let path = require('path');
let glob = require('glob');
let webpack = require('webpack');
let webpackPlugins = require('laravel-mix').plugins;
let dotenv = require('dotenv');
let SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

below code module.exports = new WebpackConfig().build();

module.exports.plugins.push(
new SWPrecacheWebpackPlugin({
cacheId: 'pwa',
filename: 'service-worker.js',
staticFileGlobs: ['public//.{css,eot,svg,ttf,woff,woff2,js,html}'],
minify: true,
stripPrefix: 'public/',
handleFetch: true,
dynamicUrlToDependencies: {
'/': ['resources/views/welcome.blade.php'],
},
staticFileGlobsIgnorePatterns: [/.map$/, /mix-manifest.json$/, /manifest.json$/, /service-worker.js$/],
runtimeCaching: [{
urlPattern: /^https://fonts.googleapis.com//,
handler: 'cacheFirst'
}
],
//importScripts: ['./js/pushmessage.js']
})
);

Full file

/**

  • As our first step, we'll pull in the user's webpack.mix.js
  • file. Based on what the user requests in that file,
  • a generic config object will be constructed for us.
    */
    let mix = require('../src/index');

let ComponentFactory = require('../src/components/ComponentFactory');

new ComponentFactory().installAll();

require(Mix.paths.mix());

/**

  • Just in case the user needs to hook into this point
  • in the build process, we'll make an announcement.
    */

Mix.dispatch('init', Mix);

/**

  • Now that we know which build tasks are required by the
  • user, we can dynamically create a configuration object
  • for Webpack. And that's all there is to it. Simple!
    */

let WebpackConfig = require('../src/builder/WebpackConfig');

let path = require('path');
let glob = require('glob');
let webpack = require('webpack');
let webpackPlugins = require('laravel-mix').plugins;
let dotenv = require('dotenv');
let SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

module.exports = new WebpackConfig().build();

module.exports.plugins.push(
new SWPrecacheWebpackPlugin({
cacheId: 'pwa',
filename: 'service-worker.js',
staticFileGlobs: ['public/**/*.{css,eot,svg,ttf,woff,woff2,js,html}'],
minify: true,
stripPrefix: 'public/',
handleFetch: true,
dynamicUrlToDependencies: {
'/': ['resources/views/welcome.blade.php'],
},
staticFileGlobsIgnorePatterns: [/.map$/, /mix-manifest.json$/, /manifest.json$/, /service-worker.js$/],
runtimeCaching: [{
urlPattern: /^https://fonts.googleapis.com//,
handler: 'cacheFirst'
},
{
urlPattern: /^https://www.thecocktaildb.com/images/media/drink/(\w+).jpg/,
handler: 'cacheFirst'
}
],
//importScripts: ['./js/push_message.js']
})
);

Create in public -> manifest.json

{
"shortname": "PWA",
"name": "PWA App",
"backgroundcolor": "#2196F3",
"theme_color": "#FFF",
"orientation": "portrait",
"icons": [{
"src": "images/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "images/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "images/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"starturl": "/",
"display": "standalone"
}

in the view

    <!-- Web Application Manifest -->
    <link rel="manifest" href="/manifest.json">
    <!-- Chrome for Android theme color -->
    <meta name="theme-color" content="#000000">

    <!-- Add to homescreen for Chrome on Android -->
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="application-name" content="PWA">
    <link rel="icon" sizes="512x512" href="/images/icons/icon-512x512.png">

    <!-- Add to homescreen for Safari on iOS -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="PWA">
    <link rel="apple-touch-icon" href="/images/icons/icon-512x512.png">

    <!-- Tile for Win8 -->
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="/images/icons/icon-512x512.png">

    <script type="text/javascript">
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker
                    .register('./service-worker.js')
                    .then(function() { console.log('Service Worker Registered'); });
        }
        window.addEventListener('beforeinstallprompt', (e) => {
            // Prevent Chrome 67 and earlier from automatically showing the prompt
            e.preventDefault();
            // Stash the event so it can be triggered later.
            deferredPrompt = e;
        });
    </script>

Tried this with ngrok to test on mobile for add to home.

Followed the tutorial from here, even though its spanish tried to figured it out
https://www.youtube.com/watch?v=ts7jDVikaN4

Source from here
https://justmegareth.com/2017-07-15-progressive-web-app-in-laravel/

Other Repo worth checking out
https://github.com/silviolleite/laravel-pwa*