Create-react-app: Service Worker caches download links

Created on 22 Sep 2017  Â·  14Comments  Â·  Source: facebook/create-react-app

Is this a bug report?

Yes

Can you also reproduce the problem with npm 4.x?

Yes

Which terms did you search for in User Guide?

Service Worker and Caching

Environment

N/A

Steps to Reproduce

The default ServiceWorker appears to cache files that it has not seen or downloaded. I have an api call which basically generates a zip to download, and is accessible via a http link. When a user navigates to this download URL by clicking on a link, the service worker intercepts the request, and tries to service the default index page.

With the ServiceWorker active, it appears that it is trying to retrieve this file from cache rather than requesting it from the server.

  1. (I think this is important) Have the homepage set to "." in the package.json config.
  2. Have a link somewhere on your application that points to a file via an API call
  3. Click on the think with the service worker active

Expected Behavior

The browser would download the file (as it does without the service worker active)

Actual Behavior

The service worker intercepts the download and serves the normal index.html file.

Suggested Behaviour

Have the whitelist exposed as a configuration so that a set of paths don't invoke the service worker.

question > PWA

Most helpful comment

my advice here (not affiliated with create-react-app) is to build the service-worker.js yourself.

you don't need to eject to take hold of this part of your project, you can leave the registerServiceWorker.js exactly as it is and do the following:

create a sw-precache config file:

// config/sw.js
module.exports = {
  staticFileGlobs: [
    'build/**/*.js',
    'build/**/*.css',
    'build/index.html'
  ],
  navigateFallback: '/index.html',
  // something like this should allow everything but files ending with `.zip`
  navigateFallbackWhitelist: [/^(?!.*[.]zip$).*$/],
  cacheId: 'my-magical-cache-machine'
}

then install sw-precache:

npm i -D sw-precache

and add something like this as part of your build script:

sw-precache --root='build/' --config config/sw.js 

this is what i've been doing in a couple of production applications for a month or two now and it works very nicely.

All 14 comments

my advice here (not affiliated with create-react-app) is to build the service-worker.js yourself.

you don't need to eject to take hold of this part of your project, you can leave the registerServiceWorker.js exactly as it is and do the following:

create a sw-precache config file:

// config/sw.js
module.exports = {
  staticFileGlobs: [
    'build/**/*.js',
    'build/**/*.css',
    'build/index.html'
  ],
  navigateFallback: '/index.html',
  // something like this should allow everything but files ending with `.zip`
  navigateFallbackWhitelist: [/^(?!.*[.]zip$).*$/],
  cacheId: 'my-magical-cache-machine'
}

then install sw-precache:

npm i -D sw-precache

and add something like this as part of your build script:

sw-precache --root='build/' --config config/sw.js 

this is what i've been doing in a couple of production applications for a month or two now and it works very nicely.

For this specific use case, using <a href='/path/to/file' download> is the standard way of telling the browser that the link is inteded to download, not navigate to, the href.

The download attribute works up until If I copy the link, and give it to someone else.

Yes, someone navigating to a random download URL that was shared with them would lead to the App Shell taking over.

The default configuration for create-react-app exempts URLs beginning with _ from triggering the App Shell, so if you wanted to avoid opting-out of the default behavior, and you have flexibility in constructing your download links, you can create them of the form _download/someId.

Or you can either disable the service worker entirely, and potentially create your own via sw-precache directly as @chee points out, or eject and modify the default configuration.

Yeah I have just disabled it for now as a workaround. I think that having to eject just to whitelist a few paths is a bit overkill though. How hard would it be to add this as a config param?

@cetra3 you don't need to eject to do what i mentioned in this comment.

that will work fine with a unejected create-react-app !

As stated in User Guide, you don't need to eject to opt out of caching:

https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#opting-out-of-caching

I think this (or prefixing URL with _) is a reasonable workaround.

The url should be prefixed with double underscores!

  • http://example.com/__auth works
  • http://example.com/_auth does not work
  • http://example.com/test/__auth does not work

@gillescastel is this approach of using double underscores to bypass serviceworker interception documented anywhere?
I have tested that it works, but I'd be much more comfortable using it in production if it was was officially supported.

@yegodz This behavior has been added in https://github.com/facebook/create-react-app/pull/2347, but was then removed in https://github.com/facebook/create-react-app/pull/3419, so AFAIK, you have to eject when using this feature. However, it may get merged back in (https://github.com/facebook/create-react-app/pull/3924) in a future realease.

hmm... looks like it is still there in the master branch.

https://github.com/ryansully/create-react-app/blob/991b092c893b916e6fd34e408e96a395d47b6008/packages/react-scripts/config/webpack.config.prod.js#L346

On Wed, May 2, 2018 at 11:02 AM, Gilles Castel notifications@github.com
wrote:

@yegodz https://github.com/yegodz This behavior has been added in #2347
https://github.com/facebook/create-react-app/pull/2347, but was then
removed in #3419 https://github.com/facebook/create-react-app/pull/3419,
so AFAIK, you have to eject when using this feature. However, it may get
merged back in (#3924
https://github.com/facebook/create-react-app/pull/3924) in a future
realease.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/create-react-app/issues/3171#issuecomment-386009129,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADOuiqVMHwa8BjLmPvkSKiW-odTGPXSCks5tucqVgaJpZM4PgS6F
.

--

--

Ruchir Godura | VP Sales | +1 814 880 9089 | [email protected]

[image: contiq logo.jpeg]
Build winning decks fast- sign up here http://contiq.com/

It was removed on the next branch which is for the 2.0 release.

Thanks @iansu
I apologize if this is not the right place to ask this question... but how can I force create-react-app to cache a particular html file without ejecting? Right now it seems to be caching only index.html, css and js files and a request for another html file is responded to with index.html.
Copying a file like xo.html to the public folder does not seem to make a difference.

never mind - just figured out.

You can overwrite create-react-app's default service worker by running sw-precache directly in package.json after react-scripts build like so:

"build": "react-scripts build && cd build && sw-precache --config ../sw-precache-config.js",

Then you can add a sw-precache-config.js file in the root folder where you can control the options for the serviceworker created by sw-precache

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JimmyLv picture JimmyLv  Â·  3Comments

wereHamster picture wereHamster  Â·  3Comments

adrice727 picture adrice727  Â·  3Comments

fson picture fson  Â·  3Comments

alleroux picture alleroux  Â·  3Comments