Answers.Body: <p>Solved it by just serving the file within a controller action like this:</p>
  
  <pre class="lang-php prettyprint-override"><code>public function actionCacheCraftServiceWorker () {
      $serviceWorkerFile = Craft::getAlias('@skayo/cachecraft/assetbundles/cachecraft/dist/js/CacheCraftServiceWorker.min.js');
  
      return Craft::$app-&gt;getResponse()-&gt;sendFile(
          $serviceWorkerFile,
          'CacheCraftServiceWorker.min.js',
          [
              'mimeType' =&gt; 'application/javascript',
              'inline' =&gt; true
          ]
      );
  }
  </code></pre>
  
  <p>and using this event to register the front-end url:</p>
  
  <pre class="lang-php prettyprint-override"><code>Event::on(
      UrlManager::class,
      UrlManager::EVENT_REGISTER_SITE_URL_RULES,
      function (RegisterUrlRulesEvent $event) {
          Craft::debug(
              'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
              __METHOD__
          );
          $event-&gt;rules['cache-craft-service-worker'] = [
              'route' =&gt; 'cachecraft/frontend/cache-craft-service-worker',
              'suffix' =&gt; '.js'
          ];
      }
  );
  </code></pre>
  
  <p>Now I can just access it with <code>https://example.com/cache-craft-service-worker.js</code> which works perfectly fine.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-09-10T16:11:13.083Z
Answers.LastActivityDate: 2019-09-10T16:11:13.083Z
Answers.UserDisplayName: Jonas Geiler
Body: <p>I am currently working on a plugin that uses a service worker which gets registered  on the front-end by some javascript code and the problem is that the service worker scope is restricted to <code>/cpresources/610c42da/</code> as the Asset Manager only serves the file from there.  </p>
  
  <p>Here's the code which I currently use to integrate with the front-end:</p>
  
  <pre class="lang-php prettyprint-override"><code>Craft::$app-&gt;getView()
                     -&gt;hook('cachecraft', function () {
                         // Pass the service worker url to the site
                         Craft::$app-&gt;getView()
                                    -&gt;registerScript(
                                        'const CACHECRAFT_SERVICE_WORKER = "' .
                                        Craft::$app-&gt;assetManager-&gt;getPublishedUrl('@skayo/cachecraft/assetbundles/cachecraft/dist/js/service-worker.js', true) .
                                        '";',
                                        1,
                                        [],
                                        'cachecraft_service_worker'
                                    );
  
                         // Register asset bundle
                         Craft::$app-&gt;getView()
                                    -&gt;registerAssetBundle(CacheCraftAsset::class);
                     });
  </code></pre>
  
  <p>So what I need is to serve my service worker from the root (<code>https://example.com/service-worker.js</code>) of the website.<br>
  Is that possible somehow?<br>
  Another possible way is to serve the file normally at <code>https://example.com/cpresources/610c42da/service-worker.js</code> BUT with a Service-Worker-Allowed HTTP Header.<br>
  But I don't know how to do that either...</p>
  
  <p>Thanks in advance for any help!</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-08T18:23:00.883Z
Comments.Text: You'd need to set up a frontend route that redirects from `/sw.js` (or whatever) to the actual URL to your resource.
Comments.UserDisplayName: andrew.welch
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-08T20:37:50.777Z
Comments.Text: @andrew.welch Oh no... I just thought it was working when I got this error:  
  `The script resource is behind a redirect, which is disallowed.`  
  I hate this so much 
  So no redirects... Need another solution...
Comments.UserDisplayName: Jonas Geiler
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-08T21:06:41.600Z
Comments.Text: @andrew.welch Okay so I finally solved it by just serving the file within a controller action. This should be good enough... Asset Manager would be better tho....
Comments.UserDisplayName: Jonas Geiler
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-09-09T21:31:04.760Z
Comments.Text: @Skayo would you mind adding your solution as an official answer in case it ends up helping someone in the future?
Comments.UserDisplayName: Brad Bell
Tags: <assets><plugins><files><scope><headers>
Title: Use Service Worker in Plugin
ThreadText: # Use Service Worker in Plugin
  
  (Asked by: username_0 on 2019-09-08)
  
  I am currently working on a plugin that uses a service worker which gets registered on the front-end by some javascript code and the problem is that the service worker scope is restricted to `/cpresources/610c42da/` as the Asset Manager only serves the file from there.
  
  Here's the code which I currently use to integrate with the front-end:
  
  ```php
  Craft::$app->getView()
                     ->hook('cachecraft', function () {
                         // Pass the service worker url to the site
                         Craft::$app->getView()
                                    ->registerScript(
                                        'const CACHECRAFT_SERVICE_WORKER = "' .
                                        Craft::$app->assetManager->getPublishedUrl('@skayo/cachecraft/assetbundles/cachecraft/dist/js/service-worker.js', true) .
                                        '";',
                                        1,
                                        [],
                                        'cachecraft_service_worker'
                                    );
  
                         // Register asset bundle
                         Craft::$app->getView()
                                    ->registerAssetBundle(CacheCraftAsset::class);
                     });
  
  ```
  
  So what I need is to serve my service worker from the root (`https://example.com/service-worker.js`) of the website.  
  Is that possible somehow?  
  Another possible way is to serve the file normally at `https://example.com/cpresources/610c42da/service-worker.js` BUT with a Service-Worker-Allowed HTTP Header.  
  But I don't know how to do that either...
  
  Thanks in advance for any help!
  
  **Tags:** assets, plugins, files, scope, headers
  
  > **Comments:**
  > **username_1**: You'd need to set up a frontend route that redirects from `/sw.js` (or whatever) to the actual URL to your resource.  
  > **username_0**: @username_1 Oh no... I just thought it was working when I got this error:   `The script resource is behind a redirect, which is disallowed.`   I hate this so much  So no redirects... Need another solution...  
  > **username_0**: @username_1 Okay so I finally solved it by just serving the file within a controller action. This should be good enough... Asset Manager would be better tho....  
  > **username_2**: @Skayo would you mind adding your solution as an official answer in case it ends up helping someone in the future?  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2019-09-10. Score: 2 | Accepted answer
  
  Solved it by just serving the file within a controller action like this:
  
  ```php
  public function actionCacheCraftServiceWorker () {
      $serviceWorkerFile = Craft::getAlias('@skayo/cachecraft/assetbundles/cachecraft/dist/js/CacheCraftServiceWorker.min.js');
  
      return Craft::$app->getResponse()->sendFile(
          $serviceWorkerFile,
          'CacheCraftServiceWorker.min.js',
          [
              'mimeType' => 'application/javascript',
              'inline' => true
          ]
      );
  }
  
  ```
  
  and using this event to register the front-end url:
  
  ```php
  Event::on(
      UrlManager::class,
      UrlManager::EVENT_REGISTER_SITE_URL_RULES,
      function (RegisterUrlRulesEvent $event) {
          Craft::debug(
              'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
              __METHOD__
          );
          $event->rules['cache-craft-service-worker'] = [
              'route' => 'cachecraft/frontend/cache-craft-service-worker',
              'suffix' => '.js'
          ];
      }
  );
  
  ```
  
  Now I can just access it with `https://example.com/cache-craft-service-worker.js` which works perfectly fine.
  
  
  ---
  
  