Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ng build for i18n - set document locale #8102

Closed
mbeckenbach opened this issue Oct 19, 2017 · 16 comments · Fixed by #15718
Closed

ng build for i18n - set document locale #8102

mbeckenbach opened this issue Oct 19, 2017 · 16 comments · Fixed by #15718
Labels
area: @angular-devkit/build-angular feature Issue that requests a new feature help wanted P5 The team acknowledges the request but does not plan to address it, it remains open for discussion
Milestone

Comments

@mbeckenbach
Copy link

mbeckenbach commented Oct 19, 2017

Bug Report or Feature Request (mark with an x)

- [] bug report
- [x] feature request

Versions.

@angular/cli: 1.4.4
node: 8.5.0
os: win32 x64
@angular/animations: 4.4.4
@angular/cdk: 2.0.0-beta.12
@angular/common: 4.4.4
@angular/compiler: 4.4.4
@angular/core: 4.4.4
@angular/forms: 4.4.4
@angular/http: 4.4.4
@angular/material: 2.0.0-beta.12
@angular/platform-browser: 4.4.4
@angular/platform-browser-dynamic: 4.4.4
@angular/router: 4.4.4
@angular/cli: 1.4.4
@angular/compiler-cli: 4.4.4
@angular/language-service: 4.4.4
typescript: 2.3.4

Repro steps.

Run a i18n build including the locale flag:

ng build --locale de.......

Then have a look at the index.html inside dist folder.
The document's locale is still set to <html lang="en"> when you build a locale "de".

This causes some browsers to suggest a translated version of the site and breaks built in spellcheckers.

The log given by the failure.

No log

Desired functionality.

The index.html in build results should contain a correct lang attribute.

<html lang="en">

Mention any other details that might be useful.

Nothing

@filipesilva filipesilva added feature Issue that requests a new feature P5 The team acknowledges the request but does not plan to address it, it remains open for discussion labels Oct 25, 2017
@filipesilva
Copy link
Contributor

@ocombe is this functionality planned planned to be supported in core?

@ocombe
Copy link
Contributor

ocombe commented Oct 25, 2017

It is not, I've actually asked this a few days ago. The answer that I was given was:

You can use DOCUMENT to easily handle that, it works both on Universal and in browser without issue

documentElement is the <html> tag as an Element which means you can use all the normal methods like (get|remove|set)Attribute()

I would add that you should probably use Renderer2 to set the attribute on the documentElement.
Here is how I would do it, on the main component:

export class AppComponent {
  constructor(@Inject(DOCUMENT) doc: Document, @Inject(LOCALE_ID) locale: string, renderer: Renderer2) {
    renderer.setAttribute(doc.documentElement, 'lang', locale);
  }
}

@ocombe
Copy link
Contributor

ocombe commented Oct 25, 2017

I wonder if setting the lang in the app (after document ready) is working for screen readers and stuff like that though, it would probably be better if the cli could set it during compilation using the html webpack plugin ?
We could ask @marcysutton, she should know

@mbeckenbach
Copy link
Author

@ocombe
At least this will not work for anything that is reading the document before angular has started.
So setting in in build would be much cleaner

@marcysutton
Copy link

Setting the lang during HTML compilation would indeed be better than client-side. It's one less thing for screen readers to wait for, although they do look at the accessibility tree as-rendered after scripting and styles have run.

@ocombe
Copy link
Contributor

ocombe commented Oct 25, 2017

Ok thanks!

@matthewharwood
Copy link

Accessibility problems and I'm pretty sure setting the lang code during runtime is also an SEO problem for crawlers looking for meta tags like hreflang.
https://support.google.com/webmasters/answer/189077?hl=en

So unless you universal/prerender pages with directive you described, SEO for i18n'd applications could suffer.

@hansl hansl unassigned Brocco Feb 6, 2018
@jacob-8
Copy link

jacob-8 commented May 16, 2019

I have this same request. @mbeckenbach, as a temporary workaround, you could create a script like this and run it after build:

`const replace = require('replace-in-file');
const langCodes = ['es', 'fr', 'hi', 'id', 'ru'];

function replaceAttributes() {
langCodes.forEach(code => {
const options = {
files: dist/${code}/index.html,
from: html lang="en",
to: html lang="${code}",
};

replace(options)
  .then(changes => {
    console.log('Modified file:', changes.join(', '));
  })
  .catch(error => {
    console.error('Error occurred:', error);
  });

})
}

replaceAttributes();`

@Squidy06
Copy link

As I'm currently fighting with angular i18n + pwa combo (a lot of things are broken, especially pre angular 8), wasted a lot of time with it.

If you also use (or plan to) @angular/pwa @jacobbowdoin 's solution will change the hashes of the dist index.html, which will actually lead you to the caching bug (Hash mismatch).

The solution would be to change the html lang before building the angular app.

@vibrunazo
Copy link

vibrunazo commented Jul 10, 2019

As a workaround I just used the "index" parameter on the build configs, in angular.json, to change the "index.html" to a new one that has the appropriate tags.

"pt": {
  "aot": true,
  "outputPath": "dist/pt/",
  "i18nLocale": "pt",
  "i18nFile": "src/locale/pt/messages.xlf",
  "index": "src/locale/pt/index.html"
 }

So each localized build can have their own "index.html". Each "index.html" is just a copy/paste of the others, except you just change the html lang attribute. This is done pre-build so it solves the problems mentioned before.

@madmurl0c
Copy link

@vibrunazo Thanks for the workaround, it's good but it's still problematic that you have to edit multiple index.html files if you want to change the favicons for example.

@ocombe Are there any news on this or will it probably be a feature of the new i18n that comes with ivy?

@ocombe
Copy link
Contributor

ocombe commented Sep 2, 2019

There's no news on this, it's not on the list of the new i18n that comes with ivy as far as I know (cc @petebacondarwin that handles it now)

@petebacondarwin
Copy link
Contributor

I might not be understanding the scope of this request but it seems to me that it has nothing to do with Angular core... the request is that the index.html that is built (via ng build) has its <html lang="en"> element modified to use the specified locale. In that case it would seem that this would be a webpack plugin to include in the CLI. cc @filipesilva ?

@ocombe
Copy link
Contributor

ocombe commented Sep 2, 2019

since the cli injects the script files into the index, it would make sense if it could change the locale as well at the same time :)

@filipesilva
Copy link
Contributor

Yes, we could replace the lang tag via a regex when building for that locale.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: @angular-devkit/build-angular feature Issue that requests a new feature help wanted P5 The team acknowledges the request but does not plan to address it, it remains open for discussion
Projects
None yet
Development

Successfully merging a pull request may close this issue.