Files
signoz/frontend/plugins
Vinicius Lourenço 013e631c68 fix(translate): do not crash on use google translate (#12466)
<!--A few plain bullets saying what changed and why, for a reviewer
skimming it - not a wall of text, not a restatement of the diff, not
generated boilerplate.-->
#### Description

This PR aims to fix the issues we have with translation, today when we
enable the translation, some parts of the app crash due to how the react
works and how the translation works.

In simple works, if you have: `<button>{(var ? 'text' : 'other text')}
{icon}` it will crash because the React will represent the `text` and
`other text` as `TextNode`, and when translate is performed, it changes
the parent of this element to `font` and causes the react to be "blind",
and when trying to delete the element, it cannot find.

> Read
https://martijnhols.nl/blog/everything-about-google-translate-crashing-react
to understand more

There's many fixes that includes ignore the errors and let the app with
invalid data, or actually go ahead and find the places with this pattern
and avoid them.

I kinda mixed two approaches, I introduced a new plugin based on
https://github.com/getcouped/eslint-plugin-react-google-translate/ but
adapted a little bit for our necessity and for our codebase (with oxc).
If we only use this plugin to find and fix the places, we will find most
of the issues crashing the app, but not all of them.

Why not all? Because even our component library is not safe enough for
google translate, eg: https://github.com/SigNoz/components/issues/351

So, I also included https://npmx.dev/package/translation-resilience,
this lib has another approach to fix the issue with the TextNode:

```
Instead of swallowing errors, this shim puts the original text nodes **back** the moment the renderer touches them:

1. A document-wide `MutationObserver` recognizes translation's displacement pattern (merge, wrap, remove — a pattern renderer commits never produce) and tracks each replaced text run as a *displacement group*: the ordered renderer-owned originals with their pre-translation values, plus the wrapper nodes currently standing in for them.
2. Patched `Node.prototype.removeChild` / `insertBefore` / `appendChild` and the `nodeValue` / `data` setters detect operations on displaced text nodes and first **restore the group** — originals go back into the wrappers' position, wrappers are removed — then let the native operation proceed on a consistent tree.
3. The translator's own observer notices the restored (now updated) text and re-translates it, so the user sees fresh, translated content. The loop is self-healing: update → restore → re-translate.

The result: no crashes, **and** live data keeps updating on translated pages — in the visitor's language.
```

We could keep the lib only and no plugin? Yes, but I want to make our
app more resilient without need the help of the lib, so we can continue
to adopt/fix places that has the pattern to crash the app, and
eventually, we can remove the lib because our app is resilient enough.

<!--Reference issues using `Closes #issue-number` to enable automatic
closure on merge. -->
#### Issues closed by this PR

Closes https://github.com/SigNoz/platform-pod/issues/2912

<!--If applicable, include screenshots or screen recordings that clearly
show the behavior before the change and the result after the change. -->
#### Screenshots / Screen Recordings


https://github.com/user-attachments/assets/0225464b-1afe-46ad-afe7-25f79e25201a

<!--Anything reviewers should keep in mind while reviewing -->
#### Additional Information

This lib has a performance cost but the lib only enable itself when it
detects the translation is enabled, so our app (and users) should not
see/perceive any performance cost due to this lib. But again, this is
another reason to slowly adapt and fix all places that offers a
potential problem to google translate.
2026-08-13 08:23:47 +00:00
..