I am learning about writing Progressive Web Apps and all of the examples use html files. I'd prefer to use EJS with a node server. Is it possible to cache the ejs so it can be used locally?
Short answer: Yes.
A service worker is going to cache a response for a given URL, so it is irrelevant of whether you will be using EJS or any other templating engine.
Of course, you need to see whether you would use the service worker to cache the template file (ex: templates/mytemplate.ejs) or the rendered HTML. If you cache the output HTML, then it will be returned from the cache and not rendered dynamically from the template on successive requests..
This may help you
Service-worker.js
const cacheName = 'pwa-demo-v1';
const filesToCache = [
'/',
'/index.ejs',
'/partials/header.ejs',
'/partials/footer.ejs',
'/css/style.css',
'/js/app.js',
'/js/menu.js',
'/images/refresh.svg',
'/images/pwa.png'
]
// Install Service Worker
self.addEventListener('install', function(event){
console.log('Service Worker: Installing....');
event.waitUntil(
// Open the Cache
caches.open(cacheName).then(function(cache) {
console.log('Service Worker: Caching App Shell at the moment......');
// Add Files to the Cache
return cache.addAll(filesToCache);
})
);
})
// Fired when the Service Worker starts up
self.addEventListener('activate', function(event) {
console.log('Service Worker: Activating....');
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(cacheNames.map(function(key) {
if( key !== cacheName) {
console.log('Service Worker: Removing Old Cache', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
self.clients.claim()
self.addEventListener('fetch', function(event) {
console.log('Service Worker: Fetch', event.request.url);
console.log("Url", event.request.url);
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
manifest.json file:
{
"name": "Progressive Web App - Demo",
"short_name": "PWADemo",
"description": "Progressive Web Apps - demo application",
"start_url": "/",
"display": "standalone",
"background_color": "#4c4849",
"theme_color": "#4c4849",
"icons": [
{
"src": "/images/192x192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/images/168x168.png",
"type": "image/png",
"sizes": "168x168"
},
{
"src": "/images/144x144.png",
"type": "image/png",
"sizes": "144x144"
},
{
"src": "/images/96x96.png",
"type": "image/png",
"sizes": "96x96"
},
{
"src": "/images/72x72.png",
"type": "image/png",
"sizes": "72x72"
},
{
"src": "/images/48x48.png",
"type": "image/png",
"sizes": "48x48"
}
],
"gcm_sender_id": "1001123745362"
}
for more details please check my repository - https://github.com/deepakgd/PWA-Demo
I think the service worker only caches the files within its scope
- It only has access to the files on its folder or “below”. Your service worker should be in your public folder not in your views folder. And when caching, you should cache all static files in your folder, then cache the url path that is rendering your views files.
Example.. '/about',
'/404',
'/admin/signup',
'/admin/signin',
That's all. I hope it helps.
Related
I'm trying to make a PWA using Vite and the Quasar framework (Vite Plugin).
My manifest and icons are all stored in the root folder of my project, but the manifest somehow can't find them.
When I run my application in dev mode, everything works fine, but when I build and host my application the manifest file gets a lot of errors:
property 'start_url' ignored, URL is invalid
property 'src' ignored,
URL is invalid
Icon URL 'android-chrome-256x256.png' failed to parse
...
This is my site.webmanifest file:
{
"name": "foo",
"short_name": "foo",
"start_url": "/index.html",
"id": "/",
"description": "foo",
"display": "fullscreen",
"background_color": "#D3D5E1",
"theme_color": "#D3D5E1",
"orientation": "portrait-primary",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-256x256.png",
"sizes": "256x256",
"type": "image/png",
"purpose": "any"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
I link to it in my index.html file: <link rel="manifest" href="/site.webmanifest" />
Could somebody please tell me what I'm missing?
It seems to me I'm doing something wrong in my relative paths, but I tried a lot to no avail.
I've also tried to place the icons in the public folder, but that didn't work.
Thanks in advance!
I am trying to build a PWA, and in that process have added a manifest file to of my webpage, but I am getting "No Manifest Detected" in the Application tab in Chrome Dev Tools.
I have seen other threads on this and have tried solutions like restarting, clearing the cache etc. but to no avail.
I tried some other tools like https://manifest-validator.appspot.com/ and they don't seem to show any issues in the manifest file.
You can also try the website at https://beegle.app/apporter-book-help and see that when you do "view source", you can find manifest file added in header and the manifest file link working fine too.
Here's how it has been added
<link rel="manifest" href="/manifest.json">
Here's how the file looks like:
{
"name": "Beegle Apporter",
"short_name": "Apporter",
"icons": [{
"src": "/beegle-logo-128x128.png",
"sizes": "128x128",
"type": "image/png"
}, {
"src": "/beegle-logo-144x144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "/beegle-logo-152x152.png",
"sizes": "152x152",
"type": "image/png"
}, {
"src": "/beegle-logo-192x192.png",
"sizes": "192x192",
"type": "image/png"
}, {
"src": "/beegle-logo-256x256.png",
"sizes": "256x256",
"type": "image/png"
}, {
"src": "/beegle-logo-512x512.png",
"sizes": "512x512",
"type": "image/png"
}],
"start_url": "/apporter-book-help",
"display": "standalone",
"background_color": "#3E4EB8",
"theme_color": "#2F3BA2"
}
Any suggestions and thoughts on what could be going wrong?
Finally managed to solve it. I was using some plugin which was adding "body" tag within "head", and somehow that was causing the manifest to not get detected.
Flutter version: 1.19.0-4.0.pre
I am trying to generate a PWA app using Flutter web, but when I open the web app, it doesn't behave as a PWA should and it doesn't show add to home screen banner either on my android device.
Here's my manifest.json file:
{
"name": "Flutter PWA Demo",
"short_name": "PWA Demo",
"start_url": ".",
"scope": ".",
"display": "standalone",
"background_color": "#FFFFFF",
"theme_color": "#E50D7F",
"description": "A Flutter pwa application.",
"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-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"
}
]
}
I tried it on master and dev but it doesn't work. It doesn't show add to home screen option on device or desktop chrome browser.
Firt become sure that you have registered "flutter_service_worker.js" in your "index.html" file, just like below:
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker.register("/flutter_service_worker.js");
});
}
Then open your pwa on chrome, right click on page and select "Inspect" option. Then go to "Application" tab and check if there is an error for "Manifest" and if there is you should fix it.
Then check "Service Workers" tab to see if "flutter_service_worker.js" is registered.
If it is registered and the "Manifest.json" file works fine, then you should see "Add to Home screen" option.
I am new to pwa and service worker, I have done the adding the manifest.json and service worker file in app. It is also showing the popup for save to home screen,
But it is not working in offline mode.
offline (using dev tool in chrome) below console error message.
The FetchEvent for "https://www.iservefinancial.com/" resulted in a network error response: the promise was rejected.
Promise.then (async)
(anonymous) # sw.js:23
sw.js:1 Uncaught (in promise) TypeError: Failed to fetch
I have also tried by changing the different urls
by trying using absolute urls like '/public/images/iserve-logo-blue.png'
and also tried by giving direct urls like in code snippet.
it is loading the resources in offline in localhost but failed to load on live server.(using chrome dev tool for offline test).
Code of the service worker file
const BASE_URL = "https://www.iservefinancial.com/";
self.addEventListener('install', function (event) {
console.log('sw installed');
event.waitUntil(
caches.open('static').then(function (cache) {
cache.addAll([
BASE_URL,
BASE_URL + 'public/js/jquery-3.2.1.min.js',
BASE_URL + 'public/images/logos/iserve-logo-blue.png',
'https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css',
BASE_URL + 'public/css/fontawesomeak.css',
BASE_URL + 'public/css/questrial-font.css'
]);
})
);
});
self.addEventListener('activate', function () {
console.log('sw Activated');
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(function (res) {
if (res) {
return res
} else {
return fetch(event.request)
}
})
);
});
The below code i have included in PHP view File
<link rel="manifest" href="<?php echo $baseurl; ?>public/scripts/manifest.json">
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js', {
scope: '.'
}).then(function () {
console.log('Service Worker Registered');
});
}
</script>
Manifest.json
{
"name": "iServeFinancial.Com",
"short_name": "iServeFinancial",
"start_url": "https://www.iservefinancial.com/",
"display": "standalone",
"orientation": "portrait",
"background_color": "#fff",
"theme_color": "#1770a3",
"icons": [{
"src": "https://www.iservefinancial.com/public/images/logos/iserve-logo-blue.png",
"sizes": "120x36",
"type": "image/png"
},
{
"src": "https://www.iservefinancial.com/public/images/logos/progressive.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "https://www.iservefinancial.com/public/images/logos/progressive1.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "https://www.iservefinancial.com/public/images/logos/progressive2.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "https://www.iservefinancial.com/public/images/logos/progressive2.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
The page should work in online as well as offline.
It seems your service worker is not in the same level with your root path.
Your sw.js is registered in /iserve/, and you try to cache js file in /public/js/.
Also you are using http://localhost/iserve/sw.js which I think is not the same domain as your live website, should be change into /iserve/sw.js or /sw.js depends on your response header.
If you want to serve your sw.js in different folder, you should add Service-Worker-Allowed:'/' in your response header.
Also here is the code how I cache my response to make web offline.
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open(CURRENT_CACHES).then(function(cache) {
return fetch(event.request)
.then(function(response) {
cache.put(event.request, response.clone());
return response;
})
.catch(() =>
cache.match(event.request).then(function(response) {
return response || caches.match('/');
}),
);
}),
);
});
My rails app and index.html file are hosted on heroku and the rest of the assets are on s3, there's a manifest.json file that is required in order to enable mobile web app mode for chrome on android that looks like:
{
"short_name": "Kinlan's Amaze App",
"name": "Kinlan's Amazing Application ++",
"icons": [
{
"src": "launcher-icon-2x.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "launcher-icon-3x.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "launcher-icon-4x.png",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "/index.html",
"display": "standalone",
"orientation": "landscape"
}
In my brocfile.js I have included the json extension to the list of fingerprintable files.
The actual file gets fingerprinted but the contents such as "src": "launcher-icon-3x.png" do not.
Anyway to do this or do I need to make an in-Repo addon to handle the creation of the file?
After looking through the source the following can be done by adding json to the replaceExtensions option:
var app = new EmberApp({
fingerprint: {
prepend: fingerprint,
extensions: ['js', 'css', 'png', 'jpg', 'gif', 'svg', 'json'],
replaceExtensions: ['html', 'css', 'js', 'json']
}
});