diff --git a/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 b/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 index 281d44554b3..c539469475e 100644 --- a/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 +++ b/app/assets/javascripts/discourse/initializers/register-service-worker.js.es6 @@ -2,27 +2,27 @@ export default { name: 'register-service-worker', initialize() { - // only allow service worker on android for now - if (!/(android)/i.test(navigator.userAgent)) { - - // remove old service worker - if ('serviceWorker' in navigator && navigator.serviceWorker.getRegistrations) { - navigator.serviceWorker.getRegistrations().then((registrations) => { - for(let registration of registrations) { - registration.unregister(); - }; - }); - } - - } else { - - const isSecure = (document.location.protocol === 'https:') || + window.addEventListener('load', () => { + const isSecured = (document.location.protocol === 'https:') || (location.hostname === "localhost"); + const isSupported= isSecured && ('serviceWorker' in navigator); - if (isSecure && ('serviceWorker' in navigator)) { - navigator.serviceWorker.register(`${Discourse.BaseUri}/service-worker.js`); + if (isSupported) { + if (Discourse.ServiceWorkerURL) { + navigator.serviceWorker + .register(`${Discourse.BaseUri}/${Discourse.ServiceWorkerURL}`) + .catch(error => { + Ember.Logger.info(`Failed to register Service Worker: ${error}`); + }); + } else { + navigator.serviceWorker.getRegistrations().then(registrations => { + for(let registration of registrations) { + registration.unregister(); + }; + }); + } } - } + }); } }; diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index 03a88119c48..069562e3e3e 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -148,9 +148,9 @@ class StaticController < ApplicationController def service_worker_asset respond_to do |format| format.js do - - # we take 1 hour to give a new service worker to all users - immutable_for 1.hour + # https://github.com/w3c/ServiceWorker/blob/master/explainer.md#updating-a-service-worker + # Maximum cache that the service worker will respect is 24 hours. + immutable_for 24.hours render( plain: Rails.application.assets_manifest.find_sources('service-worker.js').first, diff --git a/app/views/common/_discourse_javascript.html.erb b/app/views/common/_discourse_javascript.html.erb index 3ee86fa4d41..39d2fd0abb0 100644 --- a/app/views/common/_discourse_javascript.html.erb +++ b/app/views/common/_discourse_javascript.html.erb @@ -44,6 +44,9 @@ Discourse.SiteSettings = ps.get('siteSettings'); Discourse.LetterAvatarVersion = '<%= LetterAvatar.version %>'; Discourse.MarkdownItURL = '<%= asset_url('markdown-it-bundle.js') %>'; + <%- if DiscoursePluginRegistry.service_workers.present? %> + Discourse.ServiceWorkerURL = '<%= Rails.application.assets_manifest.assets['service-worker.js'] %>' + <%- end %> I18n.defaultLocale = '<%= SiteSetting.default_locale %>'; Discourse.start(); Discourse.set('assetVersion','<%= Discourse.assets_digest %>'); diff --git a/config/nginx.sample.conf b/config/nginx.sample.conf index a1f0551589f..6253e04146a 100644 --- a/config/nginx.sample.conf +++ b/config/nginx.sample.conf @@ -188,7 +188,7 @@ server { # This big block is needed so we can selectively enable # acceleration for backups and avatars # see note about repetition above - location ~ ^/(letter_avatar/|user_avatar|highlight-js|stylesheets|favicon/proxied) { + location ~ ^/(letter_avatar/|user_avatar|highlight-js|stylesheets|favicon/proxied|service-worker-.*.js) { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/config/routes.rb b/config/routes.rb index 11edecf0f9c..a7409d3afd9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -696,7 +696,9 @@ Discourse::Application.routes.draw do post "draft" => "draft#update" delete "draft" => "draft#destroy" - get "service-worker" => "static#service_worker_asset", format: :js + if service_worker_asset = Rails.application.assets_manifest.assets['service-worker.js'] + get service_worker_asset => "static#service_worker_asset", format: :js + end get "cdn_asset/:site/*path" => "static#cdn_asset", format: false get "brotli_asset/*path" => "static#brotli_asset", format: false