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:

                   ->hook('cachecraft', function () {
                       // Pass the service worker url to the site
                                      'const CACHECRAFT_SERVICE_WORKER = "' .
                                      Craft::$app->assetManager->getPublishedUrl('@skayo/cachecraft/assetbundles/cachecraft/dist/js/service-worker.js', true) .

                       // Register asset bundle

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!

  • You'd need to set up a frontend route that redirects from /sw.js (or whatever) to the actual URL to your resource. Sep 8, 2019 at 18:23
  • @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... Sep 8, 2019 at 20:37
  • @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.... Sep 8, 2019 at 21:06
  • @Skayo would you mind adding your solution as an official answer in case it ends up helping someone in the future?
    – Brad Bell
    Sep 9, 2019 at 21:31

1 Answer 1


Solved it by just serving the file within a controller action like this:

public function actionCacheCraftServiceWorker () {
    $serviceWorkerFile = Craft::getAlias('@skayo/cachecraft/assetbundles/cachecraft/dist/js/CacheCraftServiceWorker.min.js');

    return Craft::$app->getResponse()->sendFile(
            'mimeType' => 'application/javascript',
            'inline' => true

and using this event to register the front-end url:

    function (RegisterUrlRulesEvent $event) {
        $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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.