Skip to content

feat(core): add locale and no-translate attributes to html element on startup#16966

Open
Alexander-Taran wants to merge 1 commit intoeclipse-theia:masterfrom
Alexander-Taran:notranslate-n-locale
Open

feat(core): add locale and no-translate attributes to html element on startup#16966
Alexander-Taran wants to merge 1 commit intoeclipse-theia:masterfrom
Alexander-Taran:notranslate-n-locale

Conversation

@Alexander-Taran
Copy link
Contributor

@Alexander-Taran Alexander-Taran commented Feb 11, 2026

Modify html tag attributes on startup

What it does

  • Set 'lang' attribute based on detected locale.
  • Prevent auto-translation by setting 'translate="no"' and adding 'notranslate' class.

This ensures better i18n support and avoids issues with unintended UI translation.

fixes #16968

How to test

Open web application and check that html element in devtools has the right attributes respecting locale saved to localstorage via nls

Review checklist

Reminder for reviewers

Copy link
Member

@msujew msujew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution!

This works well for the main window, but doesn't seem to affect the secondary-window feature - secondary windows are still using lang="en". You can test this by popping out an editor widget for example. Do you mind fixing this as well? Afterwards, this should be good to go.

@Alexander-Taran Alexander-Taran changed the title feat(core): add locale and no-translate attributes to html element on feat(core): add locale and no-translate attributes to html element on startup Feb 11, 2026
@Alexander-Taran
Copy link
Contributor Author

@msujew how would one approach this one?
inject same code somwhere here

packages/core/src/browser/secondary-window-handler.ts

   /**
     * Sets up message forwarding from the main window to secondary windows.
     * Does nothing if this service has already been initialized.
     *
     * @param shell The `ApplicationShell` that widgets will be moved out from.
     * @param dockPanelRendererFactory A factory function to create a `DockPanelRenderer` for use in secondary windows.
     */
    init(shell: ApplicationShell, dockPanelRendererFactory: (document?: Document | ShadowRoot) => DockPanelRenderer): void {
        if (this.applicationShell) {
            // Already initialized
            return;
        }
        this.applicationShell = shell;
        this.dockPanelRendererFactory = dockPanelRendererFactory;

        this.secondaryWindowService.beforeWidgetRestore(([widget, window]) => this.removeWidget(widget, window));
    }

@msujew
Copy link
Member

msujew commented Feb 11, 2026

Yes, somewhere here probably, where the new window is instantiated:

newWindow.addEventListener('load', () => {
this.keybindings.registerEventListeners(newWindow);
// Use the widget's title as the window title
// Even if the widget's label were malicious, this should be safe against XSS because the HTML standard defines this is inserted via a text node.
// See https://html.spec.whatwg.org/multipage/dom.html#document.title
newWindow.document.title = `${widget.title.label}${mainWindowTitle}`;
const element = newWindow.document.getElementById('widget-host');
if (!element) {
console.error('Could not find dom element to attach to in secondary window');
return;
}
this.onWillAddWidgetEmitter.fire([widget, newWindow]);

@Alexander-Taran
Copy link
Contributor Author

@msujew
Cloned the code into secondary window..
Had to import nls there as well..
Not sure if it will share the same localStorage. It should though.
And weather something in secondary window already used it.

Copy link
Member

@msujew msujew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having the nls import in the secondary window code is fine and isn't technically problematic, but I don't think we need to duplicate the code. We can do this a bit cleaner, see my comments below.

Comment on lines 224 to 232
protected setNoTranslateOnHtml(): void {
document.documentElement.setAttribute('translate', 'no');
document.documentElement.classList.add('notranslate');
}

protected setLocaleOnHtml(): void {
const lang = nls.locale?.split('_').at(0) || 'en';
document.documentElement.setAttribute('lang', lang);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: document still refers to the same main document of the application. You probably want to use newWindow.document here instead. This doesn't do anything in its current form.

Comment on lines 224 to 232
protected setNoTranslateOnHtml(): void {
document.documentElement.setAttribute('translate', 'no');
document.documentElement.classList.add('notranslate');
}

protected setLocaleOnHtml(): void {
const lang = nls.locale?.split('_').at(0) || 'en';
document.documentElement.setAttribute('lang', lang);
}
Copy link
Member

@msujew msujew Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Instead of duplicating the code, I think it'd be better to have a nls.setHtmlLang(element: HTMLElement) (or similar) function available on the nls namespace that sets the translate and lang attributes as well as the notranslate class on the specified element. We can call that for both the main window document as well as any secondary window documents.

Copy link
Contributor Author

@Alexander-Taran Alexander-Taran Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@msujew do I read you right? Combine both calls in respective modules into one calling a function in nls?

Or be more explicit and do 2 calls serving kinda different purposes (set right lang/prevent auto translation)
In a spirit of better overloading I'd have them called in some method of both classes

contribution->setLocaleOnHtmlElement-> nls.boo(); nls.foo()
secondaryWindow -> setLocaleOnHtmlElement -> nls.boo(); nls.foo()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with having two functions for that as well 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@msujew moved implementations to nls.

@Alexander-Taran Alexander-Taran force-pushed the notranslate-n-locale branch 2 times, most recently from 243fa3e to c06a247 Compare February 13, 2026 10:07
startup

- Set 'lang' attribute based on detected locale.
- Prevent auto-translation by setting 'translate="no"' and adding
  '.notranslate' class.

This ensures better i18n support and avoids issues with unintended UI
translation.

Signed-off-by: Alexander Taran <a.taran@outlook.com>
@msujew
Copy link
Member

msujew commented Feb 17, 2026

@ndoschek I'm currently on vacation and can't check the validity of the latest changes. The code itself looks good to me. Can you assign someone else to give this the green light? Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Waiting on reviewers

Development

Successfully merging this pull request may close these issues.

Wrong lang attribute on html node, when locale is set to anything other than 'en'

2 participants