-
-
Save echr/a1195e083e6ff4f980698fa06ebfefc3 to your computer and use it in GitHub Desktop.
// FILE PATH: /resources/js/app.js | |
require('./bootstrap'); | |
// Import Service Worker Registry | |
require('./extensions/sw-registry'); | |
import Vue from 'vue'; | |
... |
// FILE PATH: /resources/js/firebase.js | |
import * as firebase from 'firebase/app'; | |
require('firebase/messaging'); | |
// Change with your own Sender ID | |
const initializedFirebaseApp = firebase.initializeApp({ | |
messagingSenderId: '#####' | |
}); | |
let messaging = null; | |
if (firebase.messaging.isSupported()) { | |
messaging = initializedFirebaseApp.messaging(); | |
// Change with your own VapidKey | |
messaging.usePublicVapidKey( | |
'#####' | |
); | |
messaging.onMessage((payload) => { | |
const notificationTitle = payload.notification.title; | |
const notificationOptions = { | |
body: payload.notification.body, | |
icon: '/android-chrome-144x144.png', | |
}; // Your notification icon in /public directory | |
if (!('Notification' in window)) { | |
console.log('This browser does not support system notifications'); | |
} else if (Notification.permission === 'granted') { | |
let notification = new Notification(notificationTitle,notificationOptions); | |
notification.onclick = function(event) { | |
event.preventDefault(); | |
window.open(payload.notification.click_action , '_blank'); | |
notification.close(); | |
}; | |
} | |
}); | |
} | |
export { messaging }; |
// FILE PATH: /resources/js/service-worker.js | |
importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js'); | |
importScripts('https://www.gstatic.com/firebasejs/6.3.4/firebase-app.js'); | |
importScripts('https://www.gstatic.com/firebasejs/6.3.4/firebase-messaging.js'); | |
// Change with your own Sender ID | |
firebase.initializeApp({ | |
'messagingSenderId': '######' | |
}); | |
const messaging = firebase.messaging(); | |
messaging.setBackgroundMessageHandler(function(payload) { | |
const notification = JSON.parse(payload.data.data); | |
const notificationTitle = notification.title; | |
const notificationOptions = { | |
body: notification.body, | |
icon: '/android-chrome-144x144.png', | |
}; | |
return self.registration.showNotification(notificationTitle, | |
notificationOptions); | |
}); | |
if (workbox) { | |
// injected assets by Workbox CLI | |
workbox.precaching.precacheAndRoute([]); | |
// js/css files | |
workbox.routing.registerRoute( | |
/\.(?:js|css)$/, | |
new workbox.strategies.StaleWhileRevalidate({ | |
cacheName: 'static-resources', | |
}) | |
); | |
// // images | |
workbox.routing.registerRoute( | |
// Cache image files. | |
/\.(?:png|jpg|jpeg|svg|gif)$/, | |
// Use the cache if it's available. | |
new workbox.strategies.CacheFirst({ | |
// Use a custom cache name. | |
cacheName: 'image-cache', | |
plugins: [ | |
new workbox.expiration.Plugin({ | |
// Cache upto 50 images. | |
maxEntries: 50, | |
// Cache for a maximum of a week. | |
maxAgeSeconds: 7 * 24 * 60 * 60, | |
}), | |
new workbox.cacheableResponse.Plugin({ | |
statuses: [200] | |
}) | |
], | |
}) | |
); | |
const networkFirstHandler = new workbox.strategies.NetworkFirst({ | |
cacheName: 'dynamic', | |
plugins: [ | |
new workbox.expiration.Plugin({ | |
maxEntries: 10 | |
}), | |
new workbox.cacheableResponse.Plugin({ | |
statuses: [200] | |
}) | |
] | |
}); | |
const FALLBACK_URL = workbox.precaching.getCacheKeyForURL('/offline.html'); // Your offline page, placed in /public dir, and will be cached | |
const matcher = ({ event }) => event.request.mode === 'navigate'; | |
const handler = args => | |
networkFirstHandler | |
.handle(args) | |
.then(response => response || caches.match(FALLBACK_URL)) | |
.catch(() => caches.match(FALLBACK_URL)); | |
workbox.routing.registerRoute(matcher, handler); | |
self.addEventListener('message', function (event) { | |
console.log('user request for update... (' + event.data.action + ')'); | |
if (event.data.action === 'skipWaiting') { | |
self.skipWaiting(); | |
} | |
}); | |
} |
// FILE PATH: /resources/js/sw-registry.js | |
// (optional) If you using firebase notification | |
import { messaging } from 'firebase'; | |
let newWorker; | |
// Notify user if service worker file has changed.. and need to update | |
// in your layout blade file create this snippet for notification for example | |
// | |
// <div id="sw-snackbar">A new version of this app is available. Click <a id="reload">here</a> to update.</div> | |
// | |
function showUpdateBar() { | |
let snackbar = document.getElementById('sw-snackbar'); | |
snackbar.className = 'show'; | |
} | |
document.getElementById('reload').addEventListener('click', function(){ | |
newWorker.postMessage({ action: 'skipWaiting' }); | |
}); | |
if ('serviceWorker' in navigator) { | |
window.addEventListener('load', () => { | |
navigator.serviceWorker.register('/offline.js').then(reg => { | |
reg.addEventListener('updatefound', () => { | |
newWorker = reg.installing; | |
newWorker.addEventListener('statechange', () => { | |
switch (newWorker.state) { | |
case 'installed': | |
if (navigator.serviceWorker.controller) { | |
// Show update bar | |
showUpdateBar(); | |
} | |
break; | |
} | |
}); | |
}); | |
}).catch((err) => { | |
console.log('ServiceWorker registration failed: ', err); | |
}); | |
let refreshing; | |
navigator.serviceWorker.addEventListener('controllerchange', function () { | |
if (refreshing) return; | |
window.location.reload(); | |
refreshing = true; | |
}); | |
}); | |
} |
const mix = require('laravel-mix'); | |
const WebpackShellPlugin = require('webpack-shell-plugin'); | |
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') | |
.BundleAnalyzerPlugin; | |
mix.setPublicPath('public'); | |
mix.sass('./resources/sass/app.scss', '/css/app.css'); | |
mix.js('./resources/js/app.js', '/js/webapp.js') | |
.extract(['axios', 'vue', 'accounting', 'vuex', 'vuex-router-sync', 'vue-router', 'vue-lazyload', 'vue-i18n', 'vue-events', 'vee-validate']) | |
.webpackConfig({ | |
output: { | |
chunkFilename: 'js/chunks/[name].js' | |
} | |
}); | |
if (mix.inProduction()) { | |
mix.webpackConfig({ | |
plugins: [new BundleAnalyzerPlugin()] | |
}); | |
mix.version(); | |
mix.disableNotifications(); | |
} | |
/** | |
* Publishing the assets | |
*/ | |
mix.webpackConfig({ | |
plugins: [ | |
new WebpackShellPlugin({ | |
onBuildEnd: [ | |
'npx workbox injectManifest workbox-config.js' | |
] | |
}) | |
] | |
}); |
module.exports = { | |
// Path to be offline cache | |
'globDirectory': 'public/', | |
'globPatterns': [ | |
'/**/*.{css,ico,ttf,woff,svg,png,jpg,php,js,xml,webmanifest,json,txt,gif,md,html,scss,eot,woff2,swf,otf}', | |
'offline.html', | |
'mix-manifest.json', | |
], | |
'swDest': 'public/offline.js', | |
'globIgnores': [], | |
'swSrc': 'resources/js/service-worker.js' | |
}; |
Mas maaf mau tanya, saya sedang mengerjakan project Laravel + Vuejs namun masih bingung bagaimana cara mengaktifkan PWAnya. Saya jg tidak menggunakan firebase jadi kira2 apa saja yang harus diubah ya? Terima kasih!
Mas maaf mau tanya, saya sedang mengerjakan project Laravel + Vuejs namun masih bingung bagaimana cara mengaktifkan PWAnya. Saya jg tidak menggunakan firebase jadi kira2 apa saja yang harus diubah ya? Terima kasih!
Bisa diperjelas "aktifkan" seperti apa ya yg dimaksud?, service-worker.js
dan sw-registry.js
ketika diload di app.js
akan otomatis mengaktifkan service worker dan bisa digunakan untuk fitur-fitur PWA (offline, notification, dll). Jika tidak ingin menggunakan firebase notification cukup di hapus aja script import firebase-nya.
halo gan ada tutorial gk ? cara untuk membuat notifikasi reminder menggunakan vue.js + laravel
Nice , do you have any projects with laravel ,vue and firebase ?
Nice , do you have any projects with laravel ,vue and firebase ?
how would you look in firebase ???
Good bro, Sorry for the question, can you please guide me through the process, I want to create a PWA website with Push notifications, I thought of Laravel as backend and Vue as frontend, but a friend mentioned Nuxtjs, what do you think? Do you have a guide that can help me?