fix(voting): prevent Google Translate insertBefore crash#418
Merged
Conversation
|
✅ No security or compliance issues detected. Reviewed everything up to 11d4bba. Security Overview
Detected Code Changes
|
📊 Build Bundle StatsThe latest build generated the following assets: |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a DOM-translation guard to prevent React commit-time crashes caused by in-browser translators (e.g., Google Translate) re-parenting text nodes, and installs it before the app mounts.
Changes:
- Added
installDomTranslationGuard()to patchNode.prototype.insertBefore/removeChildto avoid translator-inducedNotFoundErrorcrashes. - Installed the guard in
main.tsxbefore mounting React. - Added Vitest coverage for the re-parented-node scenarios.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/governance-app-frontend/src/main.tsx | Installs the DOM translation guard before React mounts. |
| src/governance-app-frontend/src/common/utils/domTranslationGuard.ts | Implements the insertBefore / removeChild hardening patch. |
| src/governance-app-frontend/src/common/utils/domTranslationGuard.spec.ts | Adds unit tests for the translator re-parenting cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
In-browser page translators (Google Translate) rewrite text nodes by wrapping them in their own <font> elements without React's knowledge. React keeps references to the original nodes, so a later reconcile can call insertBefore/removeChild against a node the translator re-parented, throwing "Failed to execute 'insertBefore' on 'Node'" during commit and crashing the route via the router error boundary. Users vote successfully, then see "Something went wrong". Install a one-time guard on Node.prototype.insertBefore/removeChild that appends / no-ops when the reference/child isn't a child of the parent, letting React's commit finish. Translation keeps working.
Instead of always appending when insertBefore's reference node isn't a direct child, walk up to the ancestor that is still a child of the parent (the translator's <font> wrapper) and insert before it, keeping the intended position. Append only when no such ancestor exists. Addresses review feedback.
a967b45 to
11d4bba
Compare
artkorotkikh-dfinity
approved these changes
Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
A user reported that voting crashes the app: the vote goes through, then the whole route dies with "Something went wrong" and
Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node. It only reproduces when the page is being auto-translated. In-browser translators like Google Translate rewrite text nodes by wrapping them in their own<font>elements, so React's stored node references no longer match the real DOM and the next reconcile throws during commit.Changes
domTranslationGuardthat hardensNode.prototype.insertBefore/removeChildto append or no-op when the reference/child node was re-parented by a translator, instead of throwing.main.tsxbefore React mounts.