Score:0

How to return Service Worker with custom HTTP header from custom module

ng flag

I have a custom module providing a HTML5 Service Worker file under /modules/custom/my_blocks/assets/js/service-worker.js. Since the Service Worker is not located in the root of the Drupal server, I need to return the file with an additional Service-Worker-Allowed HTTP header.

How to do that within my module?

Jaypan avatar
de flag
This isn't a Drupal issue. The file is a static file, it is not processed through Drupal, so HTTP headers need to be added through the server.
david avatar
ng flag
But I could provide the static file dynamically via Drupal, right? Hence it should also interceptable.
Jaypan avatar
de flag
Ahh I get it, Remi provided the answer for how to serve it through Drupal. That said, I would look at how to do this with `.htaccess` or whatever, so that Drupal doesn't have to be bootstrapped to serve the file.
david avatar
ng flag
`.htaccess` wouldn't work. I need to create the service worker an/or related cache files dynamically, as they need to be updated as the contents of my Drupal site change.
Score:4
vg flag

To provide a dynamic file, you need to make a Controller with a method like:

 public function serve(Request $request) {
    $file_str = $file_system->realpath($module_handler->getModule('my_module')->getPath()) . '/assets/js/service-worker.js';

    if (file_exists($file_str)) {

      $response = new BinaryFileResponse($file_str, 200);
      $response->headers->set('Content-Type', 'application/javascript');
      // Allow same origin service worker.
      $response->headers->set('Service-Worker-Allowed', '/');

      return $response;
    }

    throw new NotFoundHttpException();
  }

And then define a route for it, where the path is not existing as a static file, like:

example.serviceworker:
  path: '/serviceworker' 
  defaults: 
    _controller: '\Drupal\my_module\Controller\ExampleController::serve' 
  requirements: 
    _permission: 'access content' 

see - https://www.drupal.org/docs/drupal-apis/routing-system/introductory-drupal-8-routes-and-controllers-example.

david avatar
ng flag
Excellent clear and clean solution. That's what i was looking for. Lotta thx!
david avatar
ng flag
Fixed some small issue: Drupal doesn't intercept the "serviceworker.js" route, so I had to remove the extension. The "/serviceworker" route on the other hand works as expected.
vg flag
np ;) and thank you for the code fixes ;) Could you then also mark the answer as accepted pls ?
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.