title: Avoid cache sw.js with nginx
body: <p>I have a <code>SSR</code> React <em>Application</em> served by <code>nginx</code> reverse proxy, with a proxy caching configured for the <em>App</em> <code>location</code>. Something like:</p>
  
  <pre><code>proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=mycache:8m max_size=50m;
  proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
  proxy_cache_valid 200 302 10m;
  proxy_cache_valid 404 1m;
  
  location / {
    proxy_cache mycache;
    proxy_cache_bypass $http_cache_control;
    add_header X-Proxy-Cache $upstream_cache_status;
    # all the other configuration for this location
  }
  </code></pre>
  
  <p>I am using <a href="https://github.com/NekR/offline-plugin" rel="nofollow noreferrer">offline-plugin</a> <em>Webpack</em> plugin to handle all the <em>Service Worker</em> lifecycle and set an <a href="https://github.com/NekR/offline-plugin/blob/master/docs/updates.md" rel="nofollow noreferrer">event</a> when the SW has updates.</p>
  
  <p>Before set the <code>nginx</code> cache configuration, the SW behaviour was:</p>
  
  <ul>
  <li>after the first time loaded the <em>App</em> (and all the sw process done), browser has <code>sw.js</code> and works well without internet connection</li>
  <li>deploy new code </li>
  <li>new browser window after checking no other window with same url is open</li>
  <li><code>sw</code> detect updates, the relative process to cache new assets, then the event mentioned earlier (that in my case fires a window refresh to ensure all the content is new)</li>
  </ul>
  
  <p>After set the <code>nginx</code> cache configuration (example code shown earlier) the process described  didn't happen. The only way make it happen is to make a <em>hard-refresh</em> cleaning the <code>cache</code> of the <em>browser</em>. In that case get a fresh <code>sw.js</code> that detect changes and so on. </p>
  
  <p>Of course browsing in <em>private</em> mode fires always the events from the start (install sw, cache, etc).</p>
  
  <p>I noted that the file <code>sw.js</code> is cached (see below) and also that returns the <em>Header</em> <code>x-proxy-cache: HIT</code>, confirming that the file served is from cache.</p>
  
  <p><a href="https://i.stack.imgur.com/ZcXja.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ZcXja.jpg" alt="sw-cached"></a></p>
  
  <p>Since it's necessary to obtain always a fresh <code>sw.js</code> I tried doing something like: </p>
  
  <pre><code>location /sw.js {
    expires -1;
    add_header Cache-Control "no-store";
  }
  </code></pre>
  
  <p>But when doing this rule in the <code>nginx</code> sites-enabled configuration the <code>sw.js</code> file have a bad response. Browsing a new session I get:</p>
  
  <p><a href="https://i.stack.imgur.com/EjtHF.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/EjtHF.jpg" alt="sw-bad-response"></a></p>
  
  <p>Also found there is a <a href="https://github.com/react-boilerplate/react-boilerplate/issues/1687#issuecomment-308404079" rel="nofollow noreferrer">similar issue</a> in <a href="https://github.com/react-boilerplate/react-boilerplate" rel="nofollow noreferrer">react-boilerplate</a> but as far as I know this boilerplate don't do SSR (remarking the SSR point to show the differences, maybe helps to understand better the point  but don't know if is related to the issue).</p>