Frontend problems you might not know
As web solutions improve over time, this often comes at the cost of having a more complex system behind the scenes. When you add factors like browser compatibility or fluctuating network speeds, bugs and problems can easily occur.
In this article, I will go over a few topics I’ve found myself dealing with that are not obvious at first, leaving you wondering, “What the f is going on?”
Runtime crashes because of browser translations
Here, I mean translations that are auto-generated by the browser itself.
So why does this even cause issues? Well, the problem is pretty straightforward—something is mutating your application’s DOM tree.
Right-click in Chrome and select “Translate to X language.” The text is wrapped with new DOM elements, and your JavaScript has no idea about this change.
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Text what was translated</font></font>
This problem is especially easy to reproduce when your React code looks like this:
{showGreeting && <FormattedMessage id="greeting.title" />}
The issue here is that when the showGreeting
state changes from true
to false
, React gets confused about which elements to remove from the DOM. From React’s point of view, FormattedMessage
is a component that returns a text string, not a nested <font>
element. When it tries to remove this text from the DOM, users are greeted with this wonderful error:
Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
This is a runtime error that bubbles up to the root level. If you don’t have an error boundary set, there will be an ugly fatal error screen — sooo, pretty bad.
Even though the React code is valid, it can still cause crashes.
So what’s the solution to this? I’ve found that the cleanest way is to let React handle the mounting and unmounting at a higher level, preventing this situation from happening. However, if that’s not an option or creates code you wouldn’t normally write, wrapping the FormattedMessage
with a <span>
will also do the trick.
Playing audio or sound cues
Let’s imagine we have a chat app and we play a sound every time a user receives a message. For a better user experience, we obviously want a subtle bing to play even in inactive tabs. The problem is that browsers are not keen on playing audio that is not the result of user action.
The first thing browsers track is activity on the tab. If a user refreshes the page and then moves to other tabs, leaving our chat app inactive, the audio will not play. Discord, for example, has added a little check to deal with this issue:

Now also different browsers come into play - for example Safari decides that it just does not play audio in inactive tabs and that's it. For Chrome there is a nice article, which gives more insights to when and why audio will not be played - although, one thing to take from this is that autoplaying audio is tricky, and in web we cannot rely that audio will always play - so in many cases it’s almost necessary to grab users attention with either changing the browser tab title/text with a short interval or for example push notifications.
At my job, we are also experimenting with informing users why audio could not be played. The idea is to shift the blame from us and also make users more aware of these things.
New deployment → files not found → grey screen
A common way to improve a modern web application’s performance is to divide JavaScript into smaller chunks so that the user’s browser only downloads the necessary JS when it’s actually needed.
Now, let’s imagine a common scenario where we have a static website hosted somewhere. A user visits your website, and your application is bundled in a way that lets the user download only the JS needed for the home page. But it also retrieves the necessary info about which hashed JS chunk it needs to download if navigating to the contact page. See the problem? If you do a new deployment that updates the contact page and changes the JS chunk hash, it creates a situation where the server has a different JS chunk than the user wants to download upon navigating to the contact page.
As a result, the user will see something like this:
ChunkLoadError: Loading chunk 552 failed.
To prevent this issue, there are many different methods, and honestly, it would deserve a separate blog post to explain them properly. The easiest and most common solution I’ve seen is to build a mechanism that reloads the application upon catching this error. This is not the best UX, but it’s better than a crash screen.
How to know if it happens to your app users?
The answer here is pretty simple: you need to have some kind of error logging tool for some, for others experience + testing helps. From error logging tools my personal favorite is Sentry, but there are many other tools out there that will do the job.
Happy debugging!