We fixed several issues where Google Translate broke the Suga dashboard for users with auto-translate enabled in their browser.
Google Translate works by walking the DOM and replacing TextNode elements with <font> elements containing the translated text. This is fundamentally incompatible with React, which maintains references to the original DOM nodes. When React tries to update or remove a node that Google Translate already replaced, two things happen:
TextNode, but that node is no longer in the DOM. The translated <font> element stays unchanged, so dynamic content like form values and status indicators stop updating.removeChild on a node that Google Translate already removed, it throws a NotFoundError that can crash the entire component tree.Martijn Hols wrote an excellent deep dive on this exact issue, which informed our approach.
We took two approaches:
translate="no" attributes on interactive elements and dynamic content: dialog inputs, endpoint URLs, form fields, and status text that updates in real-time. This tells Google Translate to leave those nodes alone while still translating static UI labels and descriptions.
Wrapping conditional TextNodes in <span> elements. When React conditionally renders a text node (e.g., {isLoading ? "Loading..." : "Done"}), Google Translate can replace the bare TextNode before React swaps it out, causing the removeChild crash. Wrapping these in a <span> gives React a stable parent element to work with, which solved a large chunk of the crashes.
This is not a perfect solution (as the blog post explains, there is no complete fix for this incompatibility), but it protects the critical paths where stale or broken content would cause real problems.