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:
- The file meets all requirements.
- 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
- Add the JavaScript resource file to the root of the application’s active theme in the wpvip GitHub repository.
- 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:
/**
* 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:
- Hover over VIP in the lefthand sidebar menu of the site’s WordPress Admin dashboard.
- Select Rewrite Rules from the fly-out menu.
- Select the “Flush Rules” button at the upper right of the Rewrite Rules dashboard.