Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServiceWorker MIME Type Error ('text/html') on register (React)

The current behavior:

Service worker does not register due to the below error

The expected behavior:

Service worker registers


Details

Posted as a github issue: https://github.com/facebook/create-react-app/issues/8593

Service worker is giving the following error when attempting to register:

Error during service worker registration:
DOMException: Failed to register a ServiceWorker for scope ('http://localhost:3000/') with script ('http://localhost:3000/sw.js'):
The script has an unsupported MIME type ('text/html'). console. @ index.js:1

sw.js is showing in the sources tab of the Chrome dev tools, but not registering.

React version: 16.12.0

Error Message:

Error during service worker registration: DOMException:
Failed to register a ServiceWorker for scope ('http://localhost:3000/') with script ('http://localhost:3000/sw.js'):
The script has an unsupported MIME type ('text/html').

Failed ServiceWorker in Chrome's Inspect Tab: Chrome Error


Steps To Reproduce:

Register a Service Worker in React (change from unregister to register, or place SW code directly in index.html, or use a simpler SW. All cause the same error when running, in either dev or a build react app.)

SW Example:

export function register() {
  if ("serviceWorker" in navigator) {
    navigator.serviceWorker
      .register("./sw.js")
      .then(function(registration) {
        // Successful registration
        console.log(
          "Hooray. Registration successful, scope is:",
          registration.scope
        );
      })
      .catch(function(error) {
        // Failed registration, service worker won’t be installed
        console.log(
          "Whoops. Service worker registration failed, error:",
          error
        );
      });
  }
}

Also, `http://localhost:3000/sw.js when using the default SW from React returns this HTML:

enter image description here

Using the code sample above returns index.html (default 404, http://localhost:3000/) when trying to access http://localhost:3000/sw.js


Suggested fixes:

Move sw.js to public folder, gives this error: Public folder error


Is there a way to change the header (from text/html to application/javascript) for specifically sw.js when served to the browser in React?

I tried following some Medium articles on registering custom serviceWorkers in React, to no avail...

like image 634
Sean Moody Avatar asked Mar 03 '20 05:03

Sean Moody


People also ask

How to register a service worker in react?

Register a Service Worker in React (change from unregister to register, or place SW code directly in index.html, or use a simpler SW. All cause the same error when running, in either dev or a build react app.)

Is it possible to add SW code to react website?

The script has an unsupported MIME type ('text/html'). Register a Service Worker in React (change from unregister to register, or place SW code directly in index.html, or use a simpler SW.

What is a MIME type error?

by the way, the mime type error happens before the service worker has a chance to register (or even load its module code) - it is thrown because the server is not set up to serve this path/uri pattern, or due security restrictions in the client.

Why is my website returning a MIME type of text?

This is a very common design pattern. However, it means that any requests for unknown text files initially get redirected to index.html, and therefore return with the MIME type of "text/html", even if it’s actually a JavaScript or SVG or some other kind of plaintext file.


2 Answers

When running webpack dev server, it renders default index.html for missing resource.

If you use your browser to load http://localhost:3000/sw.js, you will actually see a rendered react app (started by the index.html). That's why the mime type is html, not javascript.

This fallback to index.html is designed to support SPA with front-end routes. For example /product/123/reviews has no such html file in backend, the JS SPA app takes care of it in front-end.

Why your file is missing? I guess you created that file in the root folder of your project.

Webpack dev server doesn't serve from that root folder.

Move your sw.js into public/ folder of your project, it will be served up as expected.

like image 188
huocp Avatar answered Sep 20 '22 09:09

huocp


This may be a duplicate of this one 61776698

Main thing you need to know: Create the serviceWorker inside public folder in order to be treated as .js file and not text/html file.

Then register that service in your index.js

Step 1, create public/sw.js

self.addEventListener('message', async (event) => {
  console.log('Got message in the service worker', event);
});

Step 2, create src/sw-register.js

export default function LocalServiceWorkerRegister() {
  const swPath = `${process.env.PUBLIC_URL}/sw-build.js`;
  if ('serviceWorker' in navigator && process.env.NODE_ENV !== 'production') {
    window.addEventListener('load', function () {
      navigator.serviceWorker.register(swPath).then(registration => {
        console.log('Service worker registered');
      });
    });
  }
}

Step 3, in src/index.js, add these two lines

import LocalServiceWorkerRegister from './sw-register';
...
LocalServiceWorkerRegister();

You can change some things for your needs, but with those changes, you should be able to work with a custom service worker in a create-react-app application

like image 21
Jhonatan Avatar answered Sep 18 '22 09:09

Jhonatan