Skip to content

Safelist service workers

A service worker uses the Web Worker API to run JavaScript in a background thread. Because JavaScript is executed in a single thread, offloading resource-intensive tasks to a service worker, simulating a second thread, can speed up site performance and offer native-app-like features (such as in-browser push notifications). Service workers are becoming more common as Google has defined them as a key part of Progressive Web Apps.

Root level requests for JavaScript resources—such as service workers—are automatically routed to PHP if:

  1. The file meets all requirements.
  2. A rewrite rule for the JavaScript resource has been added.

JavaScript resource file requirements

  • The JavaScript resource file has a .js file extension.
  • The allowed characters in the JavaScript file name are limited to: A–Z a–z _ -.

For example, a JS resource with a file path and name that can be routed automatically to PHP:
/service-worker.js

Examples of JS resource files with file paths and names that cannot route to PHP:

  • service-worker-123.js
  • service-worker-v1
  • /subdir/service-worker.js

Adding a rewrite rule for the JavaScript resource

  1. Add the JavaScript resource file to the root of the application’s active theme in the wpvip GitHub repository.
  2. Add a rewrite rule for the JavaScript resource file’s URL to the theme’s functions.php.

In this code example, a rewrite rule is added for the JavaScript resource file /service-worker.js:

functions.php
/**
 * Register the rewrite rule for JavaScript resource request.
 */
function my_theme_js_resource_rewrite() {
    add_rewrite_rule( '^service-worker\.js$', 'index.php?my_theme_serviceworkerjs=true', 'top' );
}
add_action( 'init', 'my_theme_js_resource_rewrite', 10 );
 
/**
 * Filter the list of public query vars in order to allow the WP::parse_request
 * to register the query variable.
 *
 * @param array $public_query_vars The array of public query variables.
 *
 * @return array
 */
function my_theme_serviceworkerjs_query_var( $public_query_vars ) {
    $public_query_vars[] = 'my_theme_serviceworkerjs';
    return $public_query_vars;
}
add_filter( 'query_vars', 'my_theme_serviceworkerjs_query_var', 10, 1 );
 
/**
 * Hook the parse_request action and serve the service-worker.js when custom query variable is set to 'true'.
 *
 * @param WP $wp Current WordPress environment instance
 */
function my_theme_serviceworkerjs_request( $wp ) {
    if ( isset( $wp->query_vars['my_theme_serviceworkerjs'] ) && 'true' === $wp->query_vars['my_theme_serviceworkerjs'] ) {
        /*
         * Set proper content-type
         *
         * The HTTP Content-type should be 'text/javascript', and all other Content-types should be treated
         * as an error and the content ignored.
         */
        header( 'Content-Type: text/javascript' );
 
        // The code expects an existing service-worker.js file in the root of your active theme.
        echo file_get_contents( get_stylesheet_directory() . '/service-worker.js' );
        exit;
    }
}
add_action( 'parse_request', 'my_theme_serviceworkerjs_request', 10, 1 );

When rewrite rules are added to a site, the added redirect will not work as expected until the site’s rewrite rules are flushed.

To flush rewrite rules in the WordPress Admin dashboard:

  1. Hover over VIP in the lefthand sidebar menu of the site’s WordPress Admin dashboard.
  2. Select Rewrite Rules from the fly-out menu.
  3. Select the “Flush Rules” button at the upper right of the Rewrite Rules dashboard.

Last updated: May 12, 2022