Repro: Click "Edit in MakeCode" when translating to Spanish via Google Chrome (English selected in CreateAI). We have a Spanish translation but in one group ~1/3 of users encountered this presumably due to habitual/default use of the Chrome translation feature or maybe misunderstanding of an instruction to change the language.
This is probably one of many and it may not be practical to fully avoid, but worth some investigation to see how robust it is in practice already.
Amusingly we already restructured this button's loading state to attempt to avoid a similar crash from Crowdin's dynamic text replacement for in-context translations.
One other mitigation is choosing the correct language up front. Is that merged to main? Or just on the app's branch? Let's confirm.
Some notes from Claude on options (lightly edited by me):
Detection
Chrome Translate replaces text nodes in the DOM, which is exactly what breaks React's reconciler (the classic NotFoundError: Failed to execute 'removeChild' on 'Node' when React tries to update a node that Translate has swapped out).
There's no official API to detect it, but there are reliable signals:
1. The class attribute
When Chrome translates a page, it adds translated-ltr or translated-rtl to , and sets lang to the target language. You can observe this:
jsconst observer = new MutationObserver(() => {
const html = document.documentElement;
if (html.classList.contains('translated-ltr') ||
html.classList.contains('translated-rtl')) {
// Translation is active
}
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'lang']
});
2. Font tag injection
Chrome wraps translated text in tags, which is another detectable signature.
Prevention
<meta name="google" content="notranslate"> in <head> stops Chrome (and Google Translate generally) from offering or performing translation on the whole page. Might be heavy-handed if users may genuinely want translation.
translate="no" attribute or class="notranslate" on specific elements is more surgical. Good for anything dynamic or anything React re-renders frequently. You can leave static UI chrome translatable.
The React-specific mitigation
The underlying React bug is that Translate replaces text nodes, but React holds references to the originals. The well-known workaround is to wrap any bare text in a span:
// Fragile — React holds a reference to this text node
<div>{someText}</div>
// Safer — React only touches the <span>, Translate mutates inside it
<div><span>{someText}</span></div>```
This doesn't prevent Translate running but drastically reduces the crash rate. React 18 improved things but didn't fully fix it. Wrapping FormattedMessage and useIntl calls with span generation might be worth exploring.
Approach for a warning
Since you want to warn rather than block:
MutationObserver on class/lang changes → show a dismissible banner: "Chrome's translation feature is active. This may cause the CreateAI to behave unexpectedly. Consider disabling translation for this page."
Potentially apply translate="no" to containers where unexpected DOM mutation is most likely to crash (dynamic content, frequently re-rendered regions).
Leave surrounding static UI translatable so you don't harm accessibility or users who rely on translation.
Reference or link to official translations if they exist for the language Chrome has set on the html element. Some subtlety here with language code variants and normalisation.
Repro: Click "Edit in MakeCode" when translating to Spanish via Google Chrome (English selected in CreateAI). We have a Spanish translation but in one group ~1/3 of users encountered this presumably due to habitual/default use of the Chrome translation feature or maybe misunderstanding of an instruction to change the language.
This is probably one of many and it may not be practical to fully avoid, but worth some investigation to see how robust it is in practice already.
Amusingly we already restructured this button's loading state to attempt to avoid a similar crash from Crowdin's dynamic text replacement for in-context translations.
One other mitigation is choosing the correct language up front. Is that merged to main? Or just on the app's branch? Let's confirm.
Some notes from Claude on options (lightly edited by me):
Detection
Chrome Translate replaces text nodes in the DOM, which is exactly what breaks React's reconciler (the classic NotFoundError: Failed to execute 'removeChild' on 'Node' when React tries to update a node that Translate has swapped out).
There's no official API to detect it, but there are reliable signals:
1. The class attribute
When Chrome translates a page, it adds translated-ltr or translated-rtl to , and sets lang to the target language. You can observe this:
2. Font tag injection
Chrome wraps translated text in tags, which is another detectable signature.
Prevention
<meta name="google" content="notranslate">in<head>stops Chrome (and Google Translate generally) from offering or performing translation on the whole page. Might be heavy-handed if users may genuinely want translation.translate="no" attribute or class="notranslate" on specific elements is more surgical. Good for anything dynamic or anything React re-renders frequently. You can leave static UI chrome translatable.
The React-specific mitigation
The underlying React bug is that Translate replaces text nodes, but React holds references to the originals. The well-known workaround is to wrap any bare text in a span:
This doesn't prevent Translate running but drastically reduces the crash rate. React 18 improved things but didn't fully fix it. Wrapping FormattedMessage and useIntl calls with span generation might be worth exploring.
Approach for a warning
Since you want to warn rather than block:
MutationObserver on class/lang changes → show a dismissible banner: "Chrome's translation feature is active. This may cause the CreateAI to behave unexpectedly. Consider disabling translation for this page."
Potentially apply translate="no" to containers where unexpected DOM mutation is most likely to crash (dynamic content, frequently re-rendered regions).
Leave surrounding static UI translatable so you don't harm accessibility or users who rely on translation.
Reference or link to official translations if they exist for the language Chrome has set on the html element. Some subtlety here with language code variants and normalisation.