'Setting service worker to exclude certain urls only
I built an app using create react which by default includes a service worker. I want the app to be run anytime someone enters the given url except when they go to /blog/, which is serving a set of static content. I use react router in the app to catch different urls.
I have nginx setup to serve /blog/ and it works fine if someone visits /blog/ without visiting the react app first. However because the service worker has a scope of ./, anytime someone visits any url other than /blog/, the app loads the service worker. From that point on, the service worker bypasses a connection to the server and /blog/ loads the react app instead of the static contents.
Is there a way to have the service worker load on all urls except /blog/?
Solution 1:[1]
So, considering, you have not posted any code relevant to the service worker, you might consider adding a simple if conditional inside the code block for fetch
This code block should already be there inside your service worker.Just add the conditionals
self.addEventListener( 'fetch', function ( event ) {
if ( event.request.url.match( '^.*(\/blog\/).*$' ) ) {
return false;
}
// OR
if ( event.request.url.indexOf( '/blog/' ) !== -1 ) {
return false;
}
// **** rest of your service worker code ****
note you can either use the regex or the prototype method indexOf.
per your whim.
the above would direct your service worker, to just do nothing when the url matches /blog/
Solution 2:[2]
Another way to blacklist URLs, i.e., exclude them from being served from cache, when you're using Workbox can be achieved with workbox.routing.registerNavigationRoute:
workbox.routing.registerNavigationRoute("/index.html", {
blacklist: [/^\/api/,/^\/admin/],
});
The example above demonstrates this for a SPA where all routes are cached and mapped into index.html except for any URL starting with /api or /admin.
Solution 3:[3]
here's whats working for us in the latest CRA version:
// serviceWorker.js
window.addEventListener('load', () => {
if (isAdminRoute()) {
console.info('unregistering service worker for admin route')
unregister()
console.info('reloading')
window.location.reload()
return false
}
we exclude all routes under /admin from the server worker, since we are using a different app for our admin area. you can change it of course for anything you like, here's our function in the bottom of the file:
function isAdminRoute() {
return window.location.pathname.startsWith('/admin')
}
Solution 4:[4]
Here's how you do it in 2021:
import {NavigationRoute, registerRoute} from 'workbox-routing';
const navigationRoute = new NavigationRoute(handler, {
allowlist: [
new RegExp('/blog/'),
],
denylist: [
new RegExp('/blog/restricted/'),
],
});
registerRoute(navigationRoute);
Solution 5:[5]
If you are using or willing to use customize-cra, the solution is quite straight-forward.
Put this in your config-overrides.js:
const { adjustWorkbox, override } = require("customize-cra");
module.exports = override(
adjustWorkbox(wb =>
Object.assign(wb, {
navigateFallbackWhitelist: [
...(wb.navigateFallbackWhitelist || []),
/^\/blog(\/.*)?/,
],
})
)
);
Note that in the newest workbox documentation, the option is called navigateFallbackAllowlist instead of navigateFallbackWhitelist. So, depending on the version of CRA/workbox you use, you might need to change the option name.
The regexp /^/blog(/.*)?/ matches /blog, /blog/, /blog/abc123 etc.
Solution 6:[6]
Try using the sw-precache library to overwrite the current service-worker.js file that is running the cache strategy. The most important part is setting up the config file (i will paste the one I used with create-react-app below).
- Install
yarn sw-precache - Create and specify the config file which indicates which URLs to not cache
- modify the build script command to make sure
sw-precacheruns and overwrites the defaultservice-worker.jsfile in the build output directory
I named my config file sw-precache-config.js is and specified it in build script command in package.json. Contents of the file are below. The part to pay particular attention to is the runtimeCaching key/option.
"build": "NODE_ENV=development react-scripts build && sw-precache --config=sw-precache-config.js"
CONFIG FILE: sw-precache-config.js
module.exports = {
staticFileGlobs: [
'build/*.html',
'build/manifest.json',
'build/static/**/!(*map*)',
],
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
swFilePath: './build/service-worker.js',
stripPrefix: 'build/',
runtimeCaching: [
{
urlPattern: /dont_cache_me1/,
handler: 'networkOnly'
}, {
urlPattern: /dont_cache_me2/,
handler: 'networkOnly'
}
]
}
Solution 7:[7]
Update (new working solution) In the last major release of Create React App (version 4.x.x), you can easily implement your custom worker-service.js without bleeding. customize worker-service
Starting with Create React App 4, you have full control over customizing the logic in this service worker, by creating your own src/service-worker.js file, or customizing the one added by the cra-template-pwa (or cra-template-pwa-typescript) template. You can use additional modules from the Workbox project, add in a push notification library, or remove some of the default caching logic.
You have to upgrade your react script to version 4 if you are currently using older versions.
Solution 8:[8]
Working solution for CRA v4
Add the following code to the file service-worker.js inside the anonymous function in registerRoute-method.
// If this is a backend URL, skip
if (url.pathname.startsWith("/backend")) {
return false;
}
Solution 9:[9]
To simplify things, we can add an array list of items to exclude, and add a search into the fetch event listener.
Include and Exclude methods below for completeness.
var offlineInclude = [
'', // index.html
'sitecss.css',
'js/sitejs.js'
];
var offlineExclude = [
'/networkimages/bigimg.png', //exclude a file
'/networkimages/smallimg.png',
'/admin/' //exclude a directory
];
self.addEventListener("install", function(event) {
console.log('WORKER: install event in progress.');
event.waitUntil(
caches
.open(version + 'fundamentals')
.then(function(cache) {
return cache.addAll(offlineInclude);
})
.then(function() {
console.log('WORKER: install completed');
})
);
});
self.addEventListener("fetch", function(event) {
console.log('WORKER: fetch event in progress.');
if (event.request.method !== 'GET') {
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
return;
}
for (let i = 0; i < offlineExclude.length; i++)
{
if (event.request.url.indexOf(offlineExclude[i]) !== -1)
{
console.log('WORKER: fetch event ignored. URL in exclude list.', event.request.url);
return false;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Schrodinger's cat |
| Solution 2 | Edric |
| Solution 3 | goldylucks |
| Solution 4 | Max Flex |
| Solution 5 | apaatsio |
| Solution 6 | Tope |
| Solution 7 | Ali Titan |
| Solution 8 | mleister |
| Solution 9 |
