Trouble with deep routes on a single-page app on Firebase hosting

I encountered the same behavior but the problem was unrelated to bundle.js.

My rewrites section of firebase.json looked like this:

    "rewrites": [
      {
        "source": "**",
        "destination": "index.html"
      }
    ]

and I resolved the problem by using the root relative path instead of the relative path for index.html. (Thanks Ashu!)

    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]

I heard back from Firebase Hosting. Apparently, the referenced bundle.js file in our index file needed a slash in front of it, to make it an absolute path. So this:

<script src="/bundle.js"></script>

...instead of this:

<script src="bundle.js"></script>

In case anybody else makes this same silly mistake, I hope this is useful.


[tl;dr]

This answer is only for educational purposes and in-depth insight to the problem statement and its solution. For copy/paste purposes see this answer provided by @hairbo. It is the short version and answers the question simply and nicely

Every link to resources like images, css, js can be referenced to in 3 ways:

1) Absolute Path

<script src="http://app-url.com/bundle.js"></script>

This is absolute path and resource will be loaded from the specified path without pre-processing the path provided.

2) Relative Path

<script src="bundle.js"></script>

This is relative path and it refers to the resource file as if it is located in current working directory. That is when you are on app-url.com/lvl-1 the relative path becomes app-url.com/bundle.js which provides no problems because that is actually the path to resource.

Problem

But upon going another level deep, i.e. app-url.com/lvl-1/lvl-2, current working level becomes app-url.com/lvl-1/ and the relative path is treated as app-url.com/lvl-1/bundle.js but that is not actually the path to resource. Hence the index.html file mis-behaves because it can't load the required files.

3) Root Relative Path

<script src="/bundle.js"></script>

Adding a slash (/) before the relative path makes it root relative path. In this case all non-absolute paths are treated as paths rooted at the current domain. That is, in this case the path to resource /bundle.js is treated as app-url.com/bundle.js even if current working level of url is app-url/lvl-1/lvl-2/lvl-3/...

Solution Do not use ~relative paths~. Either use absolute paths or root relative paths in all files. This way every path will be treated as expected.