Angular: [i18n] plans

Created on 2 May 2017  ·  310Comments  ·  Source: angular/angular

Here is the list of features / fixes planned for i18n.

If you want new i18n features to be added to Angular, don't hesitate to ask below and I'll let you know if that's feasible and if you should open an issue for it.
If you have a bug, open an issue (no need to discuss about it here).

For Ivy

_Note: runtime translations and most of the new features will only be available with ivy_

Features

  • [ ] Runtime i18n (one bundle for all locales with AOT) - [working on it]
  • [ ] ID migration tool (for when we break ID generation) - [PR #15621]
  • [ ] Use translation strings outside of a template - #11405 - [working on it]
  • [ ] Generate the same ID for xmb/xlf - #15136 [breaking change PR #15621]

    Issues

  • [ ] Ignore ph/ICU expressions when generating i18n ids - #15573 [breaking change PR #15621, blocked]

Not prioritized

Features

  • [ ] Allow ICU messages in attributes - #21615 [blocked, requires an update of the parser]
  • [ ] Improve Html Parser (add a new INTERPOLATION_TOKEN to the lexer output for interpolations) - #9340
  • [ ] Opt out of translation (use translate="false" attribute) - #7814
  • [ ] I18nPluralPipe should localize numbers when using "#" - #11761
  • [ ] ICU plural format (add offset & #) - #9117 [blocked, requires "Allow escaping ICU messages - #9286"]
  • [ ] Implement ICU ordinal messages
  • [ ] Auto detect TRANSLATIONS_FORMAT - #11695
  • [ ] Providing TRANSLATIONS at NgModule level - #11431
  • [ ] Add scientific number pipe - #18276
  • [ ] Opening the API - [PR #14281]
  • [ ] Throw during i18n extraction if two different contents have the same @@id - #18272

    Issues

  • [ ] Ignore leading and trailing spaces - #13114

  • [ ] allow numbers for select-icu - #17799
  • [ ] Allow escaping ICU messages - #9286 [blocked, requires an update of the parser]
  • [ ] Template Parser: Error when passing object literal as pipe parameter - #9571
i18n

Most helpful comment

I would like to see the ability to do dynamic bindings in aot mode. There are two use cases in particular to back up why this should be added to the roadmap.

The first is the basic use case where you don't want separate applications for every language. This requires some sort of redirect logic outside the app and doesn't allow dynamic changing of the language without a complete reload of the site.

The second is the case where you are embedding the app in mobile using cordova. As far as I know your choice is to jit, thus slowing down the site, creating a separate app for every language, or including every language in the app (which of course bloats it). None of these are good options. It seems Ionic doesn't use i18n, and I wonder if this is the reason why.

All 310 comments

I would like to see the ability to do dynamic bindings in aot mode. There are two use cases in particular to back up why this should be added to the roadmap.

The first is the basic use case where you don't want separate applications for every language. This requires some sort of redirect logic outside the app and doesn't allow dynamic changing of the language without a complete reload of the site.

The second is the case where you are embedding the app in mobile using cordova. As far as I know your choice is to jit, thus slowing down the site, creating a separate app for every language, or including every language in the app (which of course bloats it). None of these are good options. It seems Ionic doesn't use i18n, and I wonder if this is the reason why.

@jlutz777 those are 2 valid use case, this subject has been discussed internally lately and I've been advocating for that too. It is not easily possible yet given how i18n and AoT work in Angular, but it might be in the future once we get the new compilation process for AoT in v5.
I'll add it to the roadmap once/if we have something official and concrete about it.

I am working on Electron + Angular 2 app and now trying to add support for Localization for multiple langauge using i18n feature with Angular. Actually extraction of template-string and converting them in different language file formats are clearly documented, though I am still not able to much clear about and looking for:

  • Can i switch language dynamically? or do I need to build application separately for different language.
  • Can I manage/consolidate all strings at one place (in the form of key/value pair), so that I can change
    the string at one place to be effected at multiple place?
  • Can i access the localized file from anywhere other than template to get specific language string with
    provided key? (same as i asked above).

Points 2 and 3 will be resolved with the feature "Use translation strings outside of a template - #11405".
For the point 1 see the answer I gave to @jlutz777 above. For now you still have to build the app in multiple languages, or use JIT which can dynamically load translations at bootstrap (it's not switching at runtime, but it's still better than having to bundle it x times).

the UI language used in an application should be something that does not require building multiple versions of the same application. this should not in any way be a "compiler" issue. if it is then the compiler is flawed. the issues should be one of making the application design such that the text can be loaded from a data file at run time. that should be done with a module / library that can be loaded and used like any other. do not make that a compiler function at all.

@figuerres it's something that will be changed in the future, no promises yet but we are aware of this issue and we are looking at possible solutions, using an external file is one of them

Hi @ocombe - It looks like we're probably going to use i18n in Angular for our application. Are there any features in the docs you think might become deprecated or have breaking changes in the coming months? Any info would be greatly appreciated. And thanks again for the DVD!

Hey @rjsteinert! Glad to know that!
There's only one breaking change planned for now, it's the auto generation of IDs. The method will change and the IDs will not match anymore, but there will be a cli migration tool to update your translation files (and a parameter that you can use to only migrate when you're ready).

I googled a lot about this topic today and am wondering if there could be a "simple" solution like replacing i18n-tags with a call to a service instead of the translation?

Current:
<span i18n>Hello world</span> => rendered to <span>Hello world</span>

My idea:
<span i18n>Hello world</span> => rendered to <span>{{i18nservice.translate('pass-in-the-generated-message-id')}}</span>

This way the real translation could be done dynamically in AOT as the service could be filled from an API, file etc. and even switching locales wouldn't be much more than i18nservice.setLocale('de-DE') with loading a new source.
Text extraction with xi18n-tool would still work as before and we could leverage the message ids generated anyways to use as index for the translation service.
The current implementation would also still work flawlessly as ngc could simply look for a "--use-i18nservice" flag and otherwise compile as until now.

One problem I can currently identify is the injection of the i18nservice into each and every component as it has to exist in the components context to be callable, but that should be solvable in one way or another.

Any thoughts on this?

It is one of the things that we're considering yes, there's still the problem of how to treat code blocks inside of those translations when the compiler isn't available at runtime (AOT). It would mean that we cannot use angular components/directives/pipes inside of translations...

Yes, didn't think of that.
I'm currently developing a POC/workaround that inlines all translations into the HTML at the build step (webpack), wrapping them into ng-containers with ng-switch.
For i18n-attributes it's using a directive setting them on nativeElement.
The translations themselves also get "rendered" then to replace all those <x id=".. "/> placeholders.

It's ugly but works...can't wait for ng to support it natively.
Will publish the POC later this week, maybe it can be of use for your further conception.

I came up with a "solution" that suits my needs until there's an implementation.
The pre-loader now renders HTML for all locales before handing over to the compiler, works like a charm so far.

Repo: https://github.com/actra-development-oss/ng-i18n-aot-loader
NPM: https://www.npmjs.com/package/@actra-development-oss/ng-i18n-aot-loader

possibly a component could have an attribute that tells the system / compiler that it needs a service.
that service then takes and id and a locale and returns the localized text / markup.
all the localized text is stored on the server as resources that the service can read from.

if a component does not have the attribute no locale run-time.
if the component has it then it call get the localized data at run-time.
the compiler just builds the data files and hooks up the service.

this seems to me like a good way to handle the most common need for most applications and not require sites to build and maintain multiple copies of the same app.

I had that idea, too.
Problem is that translations can contain bindings and thus would open the system for code injection when loading translation files from external resources.
Additionally, a compiler would be needed to resolve those bindings dynamically depending on the translation.

IMHO a valid solution could be the way I implemented as POC (see comment above) to inline translations at compile time, just in a more elegant, integrated way.
Both problems mentioned above would be eliminated, only downside I can imagine is possibly the bundle size, it'd grow to "plain bundle" + (translated html-size * locales).
That could be lowered by only ng-switching the i18n-tagged html instead of the whole document but still there's a problem for i18n-*-tags.

well here is the thing; some times you have limits ....

from a practical stand point it might be better to not have that, you can have a chunk of text that can be given in multiple languages. end of the story.

you need to have a data bound chunk ? ok but that is not inside the internationalized text, it has to be separate. you can still use html and css to style and format the result. but you can't embed or combine them in every way you can think of.
like say a div or a p tag can have a number of spans one span is the text and another span is a bound date the text span is bound to the i18n locale service, the date is bound to some date service the two spans are in a paragraph tag that formats them.

Keep it simple, make it work for 95% of all users first then figure out the edge cases.

I don't see that as an edge case, it's business as usual.
Angular is a business-grade framework so many, if not all, of the i18n-users will require bindings, or at least pluralization and selects, inside texts.

<span i18n>Hello, {user.gender, select, m {Mr.}, f {Ms.}} {{user.name}}</span>
How would you solve that with separated strings?
Simple answer: you can't, as you cannot know the rules of the target language, not every language follows the format 'greeting', 'gender', 'name'.

Separating those chunks would:

  • kill context, the translator wouldn't get the meaning of the complete sentence
  • merging the chunks in the right order by CSS isn't possible, you'd have to specify rules for each and every translation, so either the CSS-guy needs to know the target languages or the translation-guy needs to know CSS, neither is acceptable.

The core i18n works in angular as expected and is usable for business-grade apps, the only thing missing apparently is AOT-compatibility, so I don't get your standpoint why a powerful, working system should be replaced by something not half that capable requiring multiple times the work to get it done.

We have a meeting tomorrow to find a solution to this problem.

@ocombe glad to hear this, i hope this leads to some good stuff for a future release of Angular , here at work we are really loving how most of it works for our development needs!

@ocombe , is it possible to change language without relaoding the entire document ? I explain :
I'm on page named "about" but when I change the language, i'm redirected to main entry page of my application .

While working on my i18n-app I also came across the known "bug" that external stylesheets from e.g. @angular/material (residing in node_modules) could not be resolved and thus the ng-xi18n-tool failed.
I implemented an "ignore missing files"-HostContext for the extraction tool, also as POC but added as PR #17845 to have it linked to the main repo.

@ocombe as you seem to be very active on this topic would you mind having a look at the PR and giving feedback?

Thanks, I'll take a look at it.

It's been few days searching a way to implement internalization on whole project including dynamic data, but found nothing concrete. Can you please suggest me something else that at least help me for the time being. Thank you.

Hello @ocombe! Can we have a follow up concerning the point raised by @jlutz777 (about dynamic bindings, thus not having one app per language) ?

Thanks a lot for your work!

@vicb is working on it right now, it'll be in 5.x (not 5.0 but most likely 5.1)

@ocombe Should the checklist be updated? I can see some of them already been merged in newer versions. And that'll better reflect your hard works. 😃

yes, good idea, I'll update it
edit: updated

Runtime i18n (one bundle for all locales with AOT) - [working on it]

Where is the associated issue / PR / discussion?

Would be cool to have an api for extending named date formats (e.g. ultraLongDate) so native date pipe would be aware of it and custom date pipe would not be needed.

Just curious about progress on "Runtime i18n (one bundle for all locales with AOT)."

My team has multiple large apps with 60+ languages. Right now we run N builds in parallel such that N is the number of languages. This is resource intensive, as you can imagine, especially considering the apps are fairly large and deploy many times a day to multiple environments.

What I'm hoping for is:

  1. Some rough ETA on runtime i18n
  2. Confirmation that runtime i18n will do a single build for all languages
  3. Whether or not each language produced will be lazy loadable or be in a single massive bundle

@chcaru while waiting for ng to provide a "native" solution have a look at https://github.com/actra-development-oss/ng-i18n-aot-loader/
It provides exactly what you're asking for, one AOT build with multiple locales.

@chcaru:
1/ rough ETA is Angular v6 (first beta should be by the end of January I believe? not sure), the good news is that code translations should follow quickly after runtime translations since almost all of the work will be done
2/ yes
3/ translations should be separated from the bundle, you'll be able to lazy load the one you need before bootstrap, or just bundle everything in one, we also want to support lazy loading translations for modules, but not sure when it'll be available

@ocombe until angularv6 is released, the most serious option to load translations dynamically and/or create a multi-languages application with a single package is ngx-translate.

Do you have some tips to help people starting using ngx-translate to easily migrate when angularv6 is out?
Any bridge between both applications?

Not really, the code is quite different... we'll see when v6 comes out with those features if I'm motivated to work on a migration tool

Hi, thanks for the transparency of upcoming features.

It would be very helpful to know answers for following questions:

  1. Any idea how different will be the new i18n workflow different from current one described in https://angular.io/guide/i18n ?

  2. Will be the i18n and i18n-* e.g. i18n-title attribute with optional custom id still available in templates?

  3. Will the following commands still work?

ng serve --aot --locale fr

ng xi18n  --i18nFormat=xlf
ng xi18n  --i18nFormat=xlf2
ng xi18n  --i18nFormat=xmb
  1. how the messages.xlf trans-units extracted from templates will be merged with the ones used in code?
  1. We will make the update experience as smooth as possible, most likely what worked before will still work after at least until v7.
  2. The i18n attributes will stay the same
  3. the extraction should be the same as well
  4. that's probably the only part that will change, I'm not sure how yet so I prefer not to tell you things that might change, but the messages will be merged at runtime when the views are created (so between bootstrap and the view appearing on the screen)

Following the @Toub's comment, for this transition period, we would be interested in having feedbacks for the following approach (mixing i18n attribute and ngx-translate) we want to implement. Our aim is to minimize the more the updates to do in the code when the new i18n support will be ready.

(Note we want dynamic locales, i.e. not one generated app per locale)

  • We will use i18n attribute so we can leverage the angular extractor tool.
  • Based on the extracted tool, we can convert xliff files (or with other formats) to contents with formats that can be used by ngx-translate (json or po)
  • We will leverage the translate attribute on elements using the i18n one to apply translations (previously extracted)

Here is a sample:

<!-- Without parameters -->
<div i18n="hello-id" translate>HELLO</div>

<!-- With parameters -->
<div i18n="hello-id" translate [translateParams]="{value: 'world'}">HELLO</div>

Thanks for your feedbacks!

Could you open an issue on ngx-translate for that? I think that the best thing would probably to update the lib to support "i18n" attributes as an alternative to "translate"

@ocombe thanks for the suggestion! Just added an issue for this on ngx-translate...

@ocombe the problem I can see is that i18n / i18n-* attributes are removed at runtime (https://github.com/angular/angular/issues/11042). Is there a way to keep them?

I checked and unless I'm mistaken they are only removed if you use Angular i18n (meaning that you load translations when you're doing the compilation).

@ocombe I understand but I don't load the translations since I'm using Angular CLI and started the application with ng serve...

@ocombe, our company will soon before an effort to support i18n using the multiple app per locale strategy that is currently prescribed. We're also planning to include the locale in the url and set the base href in the app. Once the runtime i18n feature is complete, what changes would we need to make with our url locale strategy? Is there a better way for us to begin to avoid a large refactor once runtime i18n is released? Thanks for your work on all of this.

⬆️ should say "will soon begin"

one app/locale should still be working as it is right now (minus the small change to load the locale file at bootstrap if you're not using the cli)

Could someone please target me in which file i18n attributes are removed from template durning bundle ?

cc @ocombe

It was changed in 4.2.6 (PR https://github.com/angular/angular/issues/17999)

Hi! I've been following this thread for a long time. I saw that the first beta for v6 is out. I read the changelog but did not see anything related to this longstanding issue. Any news on this front? Or at least, is there any guarantee that the interface will be similar to your polyfill?

Thanks for your work!

It's going to be in one of the last betas, or maybe RC (I know I know...).
The interface will be similar to goog.getMsg from closure since that's what google uses internally for code translations: https://developer.pubref.org/static/apidoc/global/closure/goog/getMsg.html
But we may be using a wrapper, so maybe it'll change the interface for Angular, not sure yet.
In my polyfill I use a similar interface, but with the possibility to define id, description & meaning if necessary, and I believe that we will need that one way or another (either via parameters, or via a decorator)

Thanks for all your hard work! We are preparing for a ground-up rewrite of our entire 1.x app starting in April. Is there anything we can/should do to prepare for these changes? Right now we are planning on using 6.x. Thanks again!

@ocombe Just curious when "Ignore leading and trailing spaces" will land?

I need to update the roadmap but it's a bit confused right now (even for me). This feature in particular is clearly not a priority, don't expect us working on it anytime soon

@ocombe Yeah this would be great. We too are very interested in the runtime i18n, as its the only blocking point for us. Could you maybe give a guess about its completion in %?

Thank you very much for your hard work!

@ocombe

This feature in particular is clearly not a priority, don't expect us working on it anytime soon

Could you clarify what feature you're talking about here? I don't want to make any assumptions.

@ofuangka the feature "Ignore leading and trailing spaces" is not a priority.
@Karamuto hard to guess for now, we're working on it right now

@ocombe
Could you please share your milestone about Runtime i18n (one bundle for all locales with AOT)

Now we on decide to using xi18n tools or using 3rd party libriaries for huge multilanguage project.
We hope to be able to use canonical tooling, but, aware of it's too raw.

Also we would like to be able to split xlf files (one file per module), is it possible?

up up
will runtime i18n be released in Angular 6?

thanks and happy coding!

Losing hope here, that this will be finished in time, as there is not much time left and there were no realeses so far regarding this feature.

The version 7 release would be pretty late for us.

@Karamuto #22654
I think it will be release in v6, but they have to finish Ivy first.

We should have a hello world working this week, but with minimal features (no ICU support for example).
But since it's released with ivy which is behind a flag, we'll keep working on it and release as soon as we finish a new feature, there's no need to wait for v7

@ocombe
That sounds great! It doesn't need to be complete with ICU from the get go. If it will advance in the latter realeses of v6 this is completly fine by us.

Thanks for the great work again!

@Karamuto see #22654 for a sneak peak!

Dumb question: Is there a way to have an i18n directive for string based inputs to custom components. An example when forwarding aria-labels:

I wrap a custom button that does cool things:

Custom button's template just does:

Is there a way to do this already?

@kekraft I think with static inputs you can use the i18n attribute syntax:

<custom-button ariaLabel="your label" i18n-ariaLabel></custom-button>

In the component:

<button [attr.aria-label]="ariaLabel">Some button</button>

@ocombe do you need contributors to get any of the runtime i18n work done?

Yeah ! v6 published ~~~
any update here ?

the example i18n angular 6 is here
https://github.com/angular/angular/pull/23660

@sandangel did you mean simply "everything" or "everything that is checked", from the plans at the beginning of this thread?
Was really looking forward to having a single application, I think that's one of the most important things. Went to the #23660 you linked and then reached https://pr23660-e12f469.ngbuilds.io/guide/i18n
But there it still says:

When you internationalize with the AOT compiler, you must pre-build a separate application package for each language and serve the appropriate package based on either server-side language detection or url parameters.

Is it possible to have a single application for multiple languages or not yet?

@MrCroft looks like runtime i18n is still work in progress. I read it like you some more options but not one bundle for all localizations :(

We have a working hello world but it's for the new renderer (ivy) only and since ivy is not ready for prime time, you will have to wait for that unfortunately :(

@ocombe so, unless we don't have Ivy in production (probably around v7) we will not have runtime translations. is this correct?

@ocombe are the hello world and ivy stuff publicly available? It would be cool to try and understand this new i18next implementation😃

@ocombe we are trying to implement i18n in our application, but wherever I read about it I see that we need one messages.xlf file per language. Wouldn't that become a overhead to maintain considering a complex applications with various customer facing screens etc.. I am looking to see if we can breakdown the messages file per component or per module ? Is that supported already ?

@stickler-v this file it's just transport for your strings to your translations software. don't consider to translate it manually.

I see, where do we have actual text in different languages though ? We need to manage this text manually in contrast to have translators doing it.

Sorry, but i am little lost. Based on the original documentation here https://angular.io/guide/i18n. src/app/app.component.html will only have english text. messages.fr.xlf is the file that has french text but it's auto generated and not advisable to touch it.

If I want to have app.component.html rendered using french text instead of english, where would I specify french messages "Bonjour" etc. ?

@stickler-v it's really offtopic, please create a question on StackOverflow. I will be happy to answer there.

Can you please not discuss this here, it's not the topic here, thanks
As for your question @stickler-v, one file per module / component is not possible right now, it might be in the future but it's not on the list of things that we are working on right now

Any plans to support route translations?

Sorry if this was already answered but are translations in JS possible with this version or is it still templates-only?

@santhony7 It's still not possible as Ivy isn't ready.

One question I have about the intent/functionality of runtime i18n here is if that means we will essentially be able to select the language at runtime and "flip" it without reloading the app as was the functionality in the old ng-translate for AngularJS and in ngx-translate? Or does this mean something else entirely?

No, you will have to reload the app to change the language.

With the current i18n, when you build and provide your translations, we replace the strings in the bundle code, meaning that the bundle is localized.
Runtime i18n means that the translation files are loaded when the app starts and not at build time like it is right now.
Because of that, you will be able to lazy load the translation files before the app starts which means that the bundle is separated from the language, you only get one bundle for your app.
You can also choose to have one bundle per language, and bundle the language file with your app (like we are doing right now), you'll avoid the delay required to lazy load the translations file.
In one case you do an extra http request, and in the other case not, but I don't think there will be a big enough difference to justify having one bundle per language.

Advantages of runtime i18n:

  • detect the language client side, and lazy load the translations file that you want
  • because the code is language-independent, you get one bundle for all languages
  • libraries can be "i18n" compatible as well
  • since we load the translations at runtime, we have everything that we need to provide a service that can do translations in your code as well (not just the templates)
  • we could split the translations per module (probably not available at first)

Disadvantages:

  • translating at runtime has a small cost when the translations are extracted and transformed into html nodes, but hopefully you shouldn't notice that because ivy will be a lot faster than the current renderer
  • the app bootstrap is delayed by the time it takes to lazy load the translations, or your bundle is a little bit bigger (if you bundle the translations)
  • we have to add the serializers to your app bundle to be able to read the translations, and that's a lot of code (we could probably "pre-compile" the translations into some kind of json to avoid that, we haven't decided yet)

Theoretically you could change the language without reloading the whole app, but you'll have to recreate the existing components because the templates are generated when the component is created, or you could bind the service in your template (instead of using i18n attributes) and it would be updated when you change the language. It would be possible to write a library that works like ngx-translate but uses Angular i18n internally and allows you to change the language at runtime. It would use more memory to keep the templates in sync with the language, like it's the case with ngx-translate. I'll probably write a library like this.

also for folks to think on is that some changes from one language to another may be small other may be large, say going from english to spanish is might be a "small" but from english to say Chinese or Arabic will be large.
to clarifiy for some languages it's not just the text, you may also need to design a different layout to accommodate that language and it's rules for alignment, left to right or right to left and other details.

so for most real world use i would expect the app to have at the app load a language detection step that will lead to loading the right resources and some layouts.

@ocombe Thank you very much for clarifying! I've implemented the current Angular i18n within our application and have hit a snag because of changes/unknown requirements. I'm also using the https://github.com/ngx-translate/i18n-polyfill library in conjunction to help bridge the current gap.

While the multiple bundles is a slight annoyance, you can work around it easily enough currently. The snag in particular is the potential to have one component (and all child components of it) to be displayed in a language that is different than the currently used language.

Frankly I'm uncertain yet if ngx-translate can help accomplish this for me but I wanted to message you about the upcoming changes just to make sure I had as much information possible before making any pivots.

We don't have any plan to support apps translated in multiple languages at the same time, it might be possible in the future if we can load translations / module, but it would be a side effect of the architecture, not something that we specifically tried to achieve.

Is there any ETA for Ivy + runtime i18n ?
I understand perfectly if it's not the case, but I need to know if (given the timeframe of my current project) I can wait for it or need to start using one of the current solution and postpone the migration to runtime i18n for a future version.

I won't try to give an exact time frame, every time I've tried it was wrong :D
It won't be before v7 now (will be available before as a beta)

No problem, we all know how estimations are always wrong. :D
Do you think it will be easier to migrate from the current i18n (+ i18n-polyfill) to runtime 18n or from ngx-translate ?

probably from the current i18n, but I'll write a version of ngx-translate that uses the internals of Angular i18n, if it's possible (not sure yet)

Hi, I've tried to traverse this thread to understand the current state. Is the ngx translate code currently the most viable "workaround" for a single app with dynamic loclalization?

Hi, Is it possible to change the localization at run time using ngx-translate/i18n-polyfill?

@suchg Not at runtime. You're able to do translations at runtime but you can't change the locale used.

@mjschranz thanks for the quick reply
even the run time translations is fine for now. can you share any example for the same.
I tried the example shared at https://github.com/ngx-translate/i18n-polyfill, and did change in language of chrome browser but no luck.
is there any specific method for translation ??

Please, keep the discussion here about Angular, not external libraries. If you need any help with that, post the messages on their github repositories

Hey, are there any other tracking issues or design docs on what the feature will look like in the future? Perhaps we can help with implementation or prepare ourselves to make sure the transition in v7 will be as smooth as possible.

Hi, I am currently running Angular 5 and we need to add multi language to our project.
I have added a solution that works for me now, which is almost elegant. https://github.com/angular/angular/issues/24549.

Ideally, I would like to lazy load the language files based on a country sniffer service (based an a hostname map lookup).
If that would be possible in Angular 6, that would be great.

@mattiLeBlanc How you resolve dynamic messages, for example messages from component or services?

@zverbeta Please excuse me for not fully understanding Angular Core or the context for this discussion. I can only approach it from my context for starters.

In answer to your question, I would assume that we are only interested in lazy loading the translation files (xlf) in a nice fashion, based on a locale which can be deduced from the URL or a language queryparam. ( I currently use an URL map to decide what the locale is).

A message from a component or service is not tagged like we tag the markup with i18n. I have some experience with i18n for Wordpress and PHP. There we use the __( 'text' to translate, 'text domain' ) approach to get the correct translation. This __() could also be scanned for by the CLI command creating the message file.

Is this one of issue you where referring to?

One thing I noticed with this block of markup up for example (because I was lazy and didn't want to add i18n on each subelement):

<div class="eligibility-banner" i18n="@@eligbilityBanner" fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="center center" fxLayoutAlign="center start">
        <div class="requirement-text" fxFlex="20">To be eligible, you:</div>

        <div fxLayout="column" fxFlex="80" fxLayout.gt-xs="row" fxLayoutAlign="center start">
          <div fxLayout="row" fxLayoutAlign="center center" class="requirement" fxFlex="33">
              <pro-svg icon="icon-check-circle" className="icon-check" width="44" height="44"></pro-svg>
              <div class="text">own an Australian business (with a valid ABN/ACN)</div>
          </div>
          <div fxLayout="row" fxLayoutAlign="center center" class="requirement" fxFlex="33">
              <pro-svg icon="icon-check-circle" className="icon-check" width="44" height="44"></pro-svg>
              <div class="text">are over 18 years old</div>
          </div>
          <div fxLayout="row" fxLayoutAlign="center center" class="requirement" fxFlex="33">
              <pro-svg icon="icon-check-circle" className="icon-check" width="44" height="44"></pro-svg>
              <div class="text">are an Australian Citizen or Permanent Resident</div>
          </div>
        </div>
      </div>

that is copies the whole div block into my message.xlf.
That is a lot of markup pollution. ( Of course I could use i18n on each tag that holds text. )

For this example, using the _e() command would work pretty well, I think. You would wrap your text with the echo command and all those wrapped text will be collected. You could get rid of all that markup copy in the xml.
If you need to add something dynamic to that string, you could pipe it with place holders in the string (like you would do with sprintf. Something like

<p>{{ __( 'I would like a nice %s, please', fruit ) }}</p> 

where fruit is a variable with a value of __( 'apple') or __( 'pear).
The 3 pieces of text would end up in the XML and can be separately translated.

Would that be of any use? It's pretty similar with adding the i18n attribute, I realise after reading again :)

Finally, looking at couple of the formats. XLIFF 2 looks pretty nice, bit cleaner than 1.2. The XMB looks confusing, horrible documentation that looks like it was styled in 1995.
I did notice when using XLIFF 2 that the TARGET text was not rendered like it does in version 1.2.

Have you guys looked at .pot and .mo files? Pretty simple format and also used by translated with POEdit tool.

i need to convert my application in English and Spanish using toggle button . Did all the changes ,working file separately . i have created two build under .dist/en and dist/es .Can anyone tell me , what i need to do for deployment and how to switch between both the build ?

What i need to do on click of toggle button

@shobhit12345 please post your assistance request on https://stackoverflow.com

@zverbeta the solution I posted at #24549 doesn't work when I build with --prod. Kind of obvious since I am using require which probably is not available?
Without the --prod flag the solution does work because it includes webpack related code?

@mattiLeBlanc I found this lib https://github.com/ngx-translate/i18n-polyfill and it resolve my problem with dynamic text

Hi , how we can can translate dynamic values(interpolation) using i 18 n .

    <source>This amount is for <x id="INTERPOLATION" equiv-text="{{policyName}}"/> policy #<x id="INTERPOLATION_1" equiv-text="{{policyGroupId}}"/></source>
    <target>Esta cantidad es para <x id="INTERPOLATION" equiv-text="{{**policyName**}}"/> política #<x id="INTERPOLATION_1" equiv-text="{{policyGroupId}}"/></target>

Hey! There's any place where we can track and/or help with the tasks that are been worked on? (the ones with working on it tag)

Any updates on a time frame for releasing of a beta version of runtime i18n?

@marcelnem i can't find the comment but iirc ocombe mentioned that the runtime i18n is merged for ivy so you can likely test it on the v7 beta with the ivy flag

The runtime part is done but not the compiler part, which means that you can't test it yet with ivy

Hi, I am working with Angular 6 i18n. I am working with multi-language, meaning that I followed cookbook:
https://v2.angular.io/docs/ts/latest/cookbook/i18n.html#!#ng-xi18n

My current implementation is using AOT, so I generated a messages.xlf file and a messages.pt.xlf. Everything is working fine, when I run

ng serve --configuration=pt

I get texts translated as expected. But I feel like there is something very wrong with the way it works. I am probably missing something. As far as I understood, everytime I add a new string to be translated and mark it with i18n attribute, i need to re-generate the messages.xlf file running "ng xi18n" and then update manually the messages.pt.xlf. The xlf file also holds the line number where the source is, so it looks like if i it changes the row, i will also need to re-generate the file and manually update my pt file.

<context context-type="linenumber">16</context>

That doesn't look smart, it will give me a lot of extra work to keep it working. Do you understand my concern? Am I missing something?
I know Angular 7 i18n will have a big update with Ivy being incorporated, should i wait for it?

Best Regards,
Fabio

p.s. I really hope this is not off topic, but if you feel it is, please give me at least a direction. Where should I be asking this for example? Or if there is a link that might answer my doubts.

@fabiopcarvalho One thing I've realized is it's wise to use custom IDs for every single translation to make it easier to keep track of changes in HTML layout.

But yes, you will need to routinely update the translations file.

@fabiopcarvalho I use xliffmerge to help me with the merge of the translations

Perfect, i used that tool and It worked great. I am also using the ids and
they do help.
Thanks for the reply !!

On Thursday, August 30, 2018, Pedro Romero notifications@github.com wrote:

@fabiopcarvalho https://github.com/fabiopcarvalho I use xliffmerge
https://github.com/martinroob/ngx-i18nsupport to help me with the merge
of the translations


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/angular/angular/issues/16477#issuecomment-417407822,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AWOWQ6vpjOb0Ntgpv7TUngRrBBsUIkVjks5uWCV7gaJpZM4NOSBk
.

Allowing ICU messages in attributes is critical for accessibility because attribute aria-label is used a lot in accessibility. Is there an issue for followup?

I don't think there is an issue for that, could you open one? I'm working on ICU expressions for ivy right now, so I added a TODO, but a feature request would be better

Perfect thanks (the Github search is really bad!)!

Will we be able to lazy load the translation files from an external source for example via HTTP with the new version of i18n?

@ocombe as you said you are working on Runtime i18n (one bundle for all locales with AOT). it's been over a year we are waiting. when we can expect that feature is it coming in angular 7 release?

@Sef1995 it's one of the things that we want to enable
@AhmadShahid it'll require ivy which will be released independently from v7 and ivy won't be ready for the release of v7. Some parts of ivy are already in v6 behind a flag, but it's not feature complete and you should not use it in a real world application. We don't have a release date for ivy yet.

@ocombe a quick question, if we implement i18n as of today (angular6), which will require different builds (one for each language), is the effort lost when ivy gets out and i18n runtime? I mean the way i18n would be implemented now will differ from what's coming? Trying to plan some sprints in advance and prioritise work. Thanks

We don't want to create breaking changes if we can avoid it. The ids of the extracted translations might change as we fix bugs that we've had for a long time, but we'll offer a migration tool. I cannot say for certain that it'll be 100% compatible, but expect most things to work the same, with new options available to use if you want.

@ocombe a quick question, if we implement i18n as of today (angular6), which will require different builds (one for each language), is the effort lost when ivy gets out and i18n runtime? I mean the way i18n would be implemented now will differ from what's coming? Trying to plan some sprints in advance and prioritise work. Thanks

Hi, you can use the webpack require to load in files dynamically (as a temp workaround) with one build:
Example can be found here: https://github.com/angular/angular/issues/24549#issuecomment-402013622

You do have to build with --prod --aot=false, since AOT=true will remove the webpack stuff.

@ocombe Hi,

A7 release candidate is out, As promised shall we test the runtime translation?. Runtime i18n (one bundle for all locales with AOT). How can i test this. Please help

Thanks

I second the question from @sheikalthaf although v7 has been released already.

@sheikalthaf @Shuyinsama As explained a few comments above and in the first message:
Runtime i18n requires ivy which will be released independently from v7. Some parts of ivy are already in v7 behind a flag, but it's not feature complete and you should not use it in a real world application. We don't have a release date for ivy yet.

@ocombe: What about passing dynamic i18n key from parent to child component.

Child component:
<div i18n="{{labelTextKey}}">{{labelText}}</div>

Parent component:
<app-input [labelText]="'Second name'" [labelTextKey]="'@@LabelSecondName'" ..></app-input>

I can pass it, but as the i18n translation happens at build time, the variable is at that state still empty. So, therefore no translation occurs.

Any update for such case?

@bobKasbi

you dont need the i18n tag in the child component, you can just use it in the parent like this:

<app-input i18n-labelText="@@LabelSecondName" labelText="Second name"></app-input>

@cjsase: working great. Many Thanks! Was struggling with nearly 2 Days.

Based on this: https://github.com/angular/angular/issues/21706#issuecomment-430435254

  • We should not expect ivy in v7. v8 is planned for March/April 2019. If we should not expect ivy in v7, is there a recommendation/consensus about what to use for internationalization (i18n) until ivy is released in April 2019?

This is incorrect information. Core team never said IVy would be released in 2019. Instead core team said (emphasis mine):

it should be released in any minor version, whenever it's been tested and validated

Say I have a angular 7.1.0-beta.0 app with ivy enabled, is it possible for me to have a setup with a dynamic language change issued from front with no page refresh?

if yes how? this doc : https://github.com/angular/angular/blob/master/aio/content/guide/i18n.md
and this doc : https://angular.io/guide/i18n

don't feature this?

where can I learn how to make a modern/future i18n-angular app?

@tatsujb no it's not possible, and it won't be possible even with ivy & runtime i18n. You will have to reload you Angular app if you want to change the language, for now

ok but the docs kinda apply to a chimeric version of angular like 4 minus.

I don't feel they apply to my setup nor do they cover how exactly you make the change take effect.

I'm taking it the change will have to be enforced by the backend.

In my case my angular is served in production mode by a java-spring backend. what are the big lines of what's going to happen when I press the flag icon to change language?

You take the user to www.yourdomain.com/cn/ where are have your entire Angular app compiled in Chinese. You end up with an entire compiled Angular app for every language you want to support.

@ocombe @santhony7 what about this : https://github.com/actra-development-oss/ng-i18n-aot-loader ?

could I try this?

is it badly compatible with 7.1.0-beta.0 or decently compatible?

@ocombe @santhony7 what about this : https://github.com/actra-development-oss/ng-i18n-aot-loader ?

could I try this?

is it badly compatible with 7.1.0-beta.0 or decently compatible?

I recommend using ngx-translate instead. I've used both and ngx-translate is much easier to maintain.

@digismack another difference between the two, which is a bit scary is that ngx-translate drops all of the official angular-i18n stuff and doesn't use any of it at all. it's its entire own independent circuit and the json files are much less specific about the sources of translations.

also out of the two demos ngx-translate seems much slower , what do you mean when you say it was easier to maintain?

@tatsujb as the developer of th ng-i18n-aot-loader I know it's rather hard to implement, at least integrating the loaders.
Everything else is a piece of cake as it follows the original angular i18n paradigms.

It should work with v7 as long as there have been no breaking changes in the tag structures or the-like.

trying to implement ngx-translate I'm having to go translatable place by translatable place. there's hundreds it's a bit ridiculous to me that I can't use my i18n tags I had already planned ahead with.

I'm starting to think trusting you was the wrong choice, @digismack

@tatsujb There are 58 people following this issue. Personally, I'm following it for updates from the Angular team regarding i18n. I'd appreciate if you stopped the chatter unless it's related to what the OP states:

If you want new i18n features to be added to Angular, don't hesitate to ask below and I'll let you know if that's feasible and if you should open an issue for it.
If you have a bug, open an issue (no need to discuss about it here).

If you have issues with other libraries, I suggest asking a question on StackOverflow.

It's not in my habit to write/comment issue... but I will !
Considering :
@gtbuchanan and CO are type A of person.
@tatsujb and others persons who complain/comment/expect things are type B of person

Type A you are not tired repeating always same things?!?! For me you're more annoying than type B.

due to i18n missing feature in angular Type B people are more frustrated than you who just "subscribe" to a issue (if it is to make you friends, earn some likes go on facebook i don't know, here is not place for that, you will not change word or invent something saying that!...)

I think type A can unsubscribe, wait update, check changelog quickly or read blog/news, be sure angular team will put it in big font ARIAL 72pixel that they introduce i18n dynamic translate from ts+runtime i18n: big feature missing in angular ! they didn't consider it enormously so we don't have correct i18n today, this is strategy of google or so and this can't change !

People B wait this feature 2 years ago, https://github.com/angular/angular/issues/9104#issue-159302131 yes since angular 2.X !

I just want say please respect frustrated type B and don't be evil. If nobody complain a lot about i18n i think i18n improvement wont be considerated for years to come, this is aprt of open source too ! complain critics ! strategy can change ! so leave people complain, unsbscribe , you are best than other you can find your information without subscribing to this issue !

Type B please continue complain/comment until you can ! it is the only best way to understand people's need !

Strike Strike lol

@tatsujb It all comes down to personal preference. When I last implemented ng-i18n-aot-loader I had to run an ejected build and customize the webpack config in order to get it working. Maybe that is no longer the case. However, running an ejected build meant that the Angular CLI tools were no longer usable. So, I found it easier in the long run to implement ngx-translate and deal with the fact that it works a little differently.

@gtbuchanan I feel your pain, but this "chatter" is directly related to the scope of the features mentioned in OP's post. Since the timeframe for Runtime i18n (one bundle for all locales with AOT) has continued to slip, people are still coming to this thread to look for current solutions.

@ocombe, we are about to start a new project now, where we will get the translations from a database.
Our Angular Modules will be loaded lazily and we also would like to stay as close as possible to what Angular offers regarding I18N.

Since Angular I18N support did not make it into the latest release as planned - do you have any recommendation for us and others who are about create new projects just now?

For example, until I18N is ready, we could use ngx-translate, but then I read somewhere in the github issues of that project, that it will not support lazy loading, which would be a show stopper for us.

Then on the other hand, Angular's I18N support is not ready for prime time yet.

I really would appreaciate some hints pointing us into the right direction about what to use for the upcomming project - ngx-translate vs ?

Must Haves:

  • lazy loading

Nice to Have:

  • ICU expressions

Merci

For the followers of this issue, @ocombe will talk about runtime i18n at angularconnect in a couple of hours. I assume at least some of the open questions will be answered there. there is a livestream available

@ctaepper - thank you very much for the info!

@guygit this might be ngx-translate or angular-l10n. here's the comparison table created by me https://medium.com/@sergeyfetiskin/tools-to-translate-your-angular-app-c021e25ff26a

for our apps, we decided to go Angular way even it has some limitations.

@fetis Thank you very much - I'll take a look :-)

Wondering about the choice of XLIFF files for the translation files - Google Translate Toolkit as well as Flutter/Dart i18n both support ARB files and do not support XLIFF. I've heard that ARB file support is not planned, but wondering if this is something that might be considered again. Or if someone (@ocombe ?) could point at where Angular interacts with the XLIFF files so I can look at how hard it would be integrate ARB support.

(For some context, we are going to be using Flutter/Dart for our mobile apps and Angular for our web app, and would really like to share our translation files between both mobile and web if at all possible. I'm considering writing an ARB -> XLIFF convertor if there is no appetite for consider its inclusion in Angular.)

@localpcguy if you end up writing a converter kind of thing, you might be interested to contribute it to https://github.com/translate/translate which is already offering conversion from/to a lot of formats.

On a side note, ocombe said a few months ago that he would push hard to support PO files (and JSON?). Hopefully it will happen at some point, because we had a hard time to find ockay-ish tools to work with XLIFF.

because we had a hard time to find ockay-ish tools to work with XLIFF.

@PowerKiKi that's simply not true. Almost any online translation management tool supports XLIFF format. And there're even free desktop translation programs if you don't want to edit .xliff manually

@fetis I hate to go off topic but have found quite a lot of pain in regards to using XLIFF with tools. See my comment here: https://github.com/angular/angular/issues/20193#issuecomment-345755889

Please provide references to such tools, because we still haven't found anything good and have still yet to find something that supports XLIFF 2. Smart Cat looks pretty but updating strings in it makes me want to gauge my eyes out.

It seems you know something we don't :)

Pootle uses https://github.com/translate/translate and was really great with Gettext (po files) but it doesn't support placeholders/tags and they're waiting for a contribution from someone to add it

I've been subscribed to this issue for a long year or so. It seems progress in this regard is not a priority for the Angular team, and having to compile the app once for every language and going through hoops to do dynamic translations is not acceptable. I reccomend, if you are able to do so, to create a custom pipe which uses whichever other i18n library you like. Being pure, this pipe will be equally efficient to compiling the app multiple times. Also, by using a i18n that does not depends on Angular, you will be able to do dynamic translations from code trivially. Another advantage is that your translations will no longer depend on Angular, so you can start migrating some components to other frameworks if you wish, or you can even choose the translation format and tools you prefer with total freedom. I am using https://airbnb.io/polyglot.js/ and very happy with it, and even when the migration of my app from Angular i18n to polyglot is still going on, I cannot be more happy with the result and the removal of the dependency with Angular i18n.

Sorry to the ones that will receive this as a notification on your mail and do not care about my opinion, but since it has been so long reading your notifications I feel I have to say goodbye before unsubscribing :)

Cheers!

It seems progress in this regard is not a priority for the Angular team, and having to compile the app once for every language and going through hoops to do dynamic translations is not acceptable.

Runtime i18n is a big priority for the Angular Team. However, the blocking issue it the new Ivy renderer. The project progress is good so far and we can probably expect Ivy for Angular 8. I understand that this is a difficult situation for everyone involved. There are plans but they cannot be implemented as long as Ivy is not finished.

Please see the talks from the recent AngularConnect conference (2018) in London, especially "Runtime i18n" by Olivier Combe and the Day 2 keynote by Alex Rickabaugh.

Indeed my experience is similar to @intellix.

XLIFF 1.2 is 10 years old, yet support for it in open source projects seems to be quite poor. Pootle does not support palceholders according to https://github.com/translate/pootle/issues/4762 and https://github.com/translate/pootle/issues/1811. Weblate does not support them either, though a PR might add support soon.

On desktop, Virtaal _does_ support XLIFF placeholders, but the latest release 0.7.1 is 6 years old and does not work on latest macOS anymore from what I heard. It unfortunately does not give the impression of a well-maintained project, with a few very old PR that are still waiting to be merged in spite of their apparent simplicity. And a very low commit activity in the last few years.

I just found out that Poedit 2.2 released a few days ago support XLIFF 1.2 and 2.0. I unfortunately cannot test it as I get an error from snapcraft.io CDN when installing at the moment. But this might be the best solution for desktop users.

@fetis if you found some open source (or at least free to use) projects to edit XLIFF 1.2, or better yet XLIFF 2.0, with support for placeholders, please list them here. Everything else I tested was either not working at all, or abysmally complex to use.

@intellix @PowerKiKi here's the list what I know. Our target is an online translation platform, where we can collaborate with translators/colleagues from different countries. Going through the process of installing desktop software for every collaborator and manage XLIFF files synchronization is not a choice for us. So, I didn't test desktop tools, platforms I did.

Applications
OmegaT
https://omegat.org/

Self-hosted
https://weblate.org/en/ +paid hosting
https://pootle.translatehouse.org/
https://pontoon.mozilla.org/

Platforms
Crowdin
https://crowdin.com/
CLI support

WebTranslateIt
https://webtranslateit.com/
CLI support

Transifex
https://www.transifex.com/

PhraseApp
https://phraseapp.com/

Lokalise
https://lokalise.co/
CLI support

_I think we'll finish with Lokalise for our projects as it provides enough functionality with affordable price._

~POEditor~
https://poeditor.com/pricing/
Declared XLIFF support doesn't work with Angular format

If you're looking for an open-source solution, this list might me useful https://opensource.com/article/17/6/open-source-localization-tools

Side nodes
I didn't see an online platform that supports XLIFF 2.0 and it was a big surprise for me. XLIFF 1.2 is officially marked as deprecated and nobody in the industry did a support for v2.

Happy to hear that POEdit declared XLIFF support, I used it for .po files and that was nice.

P. S. I'm very sorry to make an offtopic here, but at the same time getting XLIFF file from your app is only part of the journey, you need to translate and maintain it through your app lifecycle. So it's important discussion. I would suggesting to move somewhere, I can put this list as an Medium article and we can keep discussion there.

@localpcguy there are many formats, but it all comes down to how many we can support. Writing and maintaining a serializer takes time. Xliff 2 was added as a PR by somebody else, that's why we added the support (otherwise we wouldn't have taken the time to support it).
We need a serializer for two things: extraction, and merge.
I haven't talked about this at Angular Connect, but my hope is that we should be able to use an external serializer. It should be very easy to do that for runtime (merge) with ivy, but extraction is still complicated because the serializer needs to be updated when we make changes to the compiler.
I've got a few ideas on how to do that, but I'll have to talk to the team about it once ivy lands. What I'd really love to do would be to at least add JSON support so that I can rewrite ngx-translate using Angular i18n (and because so many people want it).

Thanks @ocombe (and all the other inputs, I like seeing the various views). It looks like #14185 was the PR you mentioned, is that still a good starting place if I want to look at adding ARB support? Is that something that could potentially be merged if submitted?

@localpcguy we have a meeting tomorrow where we'll discuss that (and other things), I'll let you know how it goes

ok so here's what we think would work: for the extraction we'll extract strings in some kind of json format (might even be ARB since it's an official json format for translations) that anyone can take and postprocess to whatever format you want to use (json is really easy to use), and for runtime we'll provide some kind of interface that you can use to write your own loader that understands your format.

So this pretty much means, that we are free to use any kind of format for translations as long as we can provide a loader for the app?

Well this would awesome :+1:

yes, you wouldn't have access to deep optimizations (replace strings at build time to create one bundle per language, meaning that translations would be code splitted with your components), but you could use any kind of lazy loading solution that you want, as long as you load all the translations when the app starts (they need to be loaded synchronously before a component is created)
you could also eventually code split them manually and load them with the router asynchronously when you load a new component, that'd be up to you, using the new lazy loading functionalities that ivy provides (Jason did a demo of that at Angular Connect)

can we expect a beta demo (not files just a video or livestream) of switching language on the fly on Ivy? trying to put together a POC pre-final ivy might be a great way to detect down the line barrages.

not that I disagree with the approach of waiting for a more set-in stone ivy before poring developer sweat into live-i18n, I think that a one-man small-scale POC is a small amount of sweat for immense return in the form of foresight and could potentially avoid live-i18n being pushed into 2020.

The runtime service for external users isn't done yet, we only have the code that uses closure (goog.getMsg) because that's what we needed to tests ivy with Google apps.
I'll be working on this now for the coming months. This means that you probably can't use i18n with ivy yet.
The code for runtime i18n was just merged yesterday, and the compiler code for i18n should be merged in the next few days (we're getting there!). Then we'll work on the new service for external people, including the new loaders that I talked about just above, and the service to use translations in your code.

As for switching the language on the fly, it would still require a full reload of the app, or maybe a route change (that would cleanup all existing components). I wouldn't try working on a POC yet.

As for switching the language on the fly, it would still require a full reload of the app, or maybe a route change (that would cleanup all existing components). I wouldn't try working on a POC yet.

that's fair, ...however not requiring a full reload of the app (or anything that accomplishes seamlessness in the end-user's eyes, AKA not loosing store, nor authentication, nor url (well... not accounting for /en/...) and all within a reasonable delay) ....is still the plan, right?

@tatsujb Reloading the app isn't reloading the page, StackBlitz reloads the app on every edit, do you feel it's observable to your eyes?

Reloading the app means unmount the app and then mount the app in same position, equivalent to a SSR-CSR transition (it's CSR-CSR), and there should be no async tasks in subsequent bootstrap process if a proper cache architecture being considered.

so with this correct setup; store variable values and authentication (as well as scroll amount on scrollable divs) would remain?

@tatsujb As long as they're stored outside Angular-created instance, for example in lexical variable or window property.

@trotyl How do you reload the app without the page?

@saithis You always bootstrap the application by platformBootstrap().bootstrapModuleFactory() (or other equivalent) imperatively, you can call it anytime anywhere, there's no magic at call (except Angular CLI currently have some limitation for code replacement, should no longer be a problem in Ivy).

Bootstrap eagerly at script invocation time and keep it forever (do not unmount) is only a common practice for SPA, but no one is forcing you doing that.

EDIT: in case of someone doing so, it's also required to destroy the bootstrapped NgModuleRef to prevent memory leak. These are off-topic question and better to be discussed in other channel, better to keep track on i18n discussion here.

@trotyl Thanks, I didn't know that bootstraping again works.

@ocombe could you plz remove spam here? and my comment as well.

  1. to @fetis : people like you should unfollow issue & subcribe for release
    image

  2. to @Andrulko : we don't care

  3. to @ angular : as said i perfectly understand complains here! like we wanted ivy for v7 not for vX or don't sell big improve for v7 while you couldn't respond for it or you will put it in 7.x just to respect your deadline... this is not fair! yes option should be to not announce anything and nobody will complains this is bad idea too, you need make your place in framwork. yes we wait correct i18n since v2, in this mandatory aspect for big app you couldn't sell angular ready for big app like international webapp which contain 50000strings, of course you certainly don't like read this but it is without compassion and with good faith, imho if we don't consider i18n and slow build time/dev time for all others aspects i can say angular is awesome. certain direction should change at the top, im speaking to deciders of course. hight exception from us (which criticize) because from big-google we couldn't make big mistake like this. i see google developers like exceptionels- smart people without mistake this things shouldn't happen for experienced developers and for devteam like google ! my global opinion don't sell angular 100% for big app when company choose it then sell/explain private-company what is open source !

  4. @ all especially for those not workin in business company: dislike my coment because i certainly don't respect open source?!?!, lol go say this to my boss to wait.. to wait... after choosing angular because we believe it is ready (100% not 80%) for big app... we depend!

this is my last comment here because we leave the ship! unsubscribe + not choose angular in my next project (you could say your are winner, open source project don't need people like us)

Such passion! Just for balance...we rewrote our app in Angular 6, internationalized in 6 language, and have only felt minor inconveniences. Sure, faster build times and translations on the fly would certainly be nice but not the end of world for us. The 98% of the framework that is not i18n is awesome. Great job guys! Looking forward to new features.

We also have a fantastic experience with Angular for our new enterprise portal. The i18n is the last missing feature we need since, in Switzerland, we have to support four languages. I think the issue here is with communication. For project planning, if we had a better estimation of i18 release a year ago, we could have planned for it and consider other possibilities. That said, we are looking forward to hearing any updates. :-)

In defence of angular, you can simple enough use it in production like this (best solution I found)

  1. Wrap translated variable text in own component to move translation logic somewhere
parent-component.component.html

<app-route-translation
  [routeData]="routeData"
></app-route-translation>

route-translation.component.html

<span
  i18n="route text|Navigation text for route@@routeText"
>{
  routeData.langKey, select,

  home-1 {Home 1}
  home-1-1 {Home 1-1}
  home-1-2 {Home 1-2}
  home-2 {Home 2}
  home-2-1 {Home 2-1}
  home-2-2 {Home 2-2}
  home-root {Home root}
  lazyPage {Lazy page}
  notFound {404}

  other {Other}
}</span>
  1. Configure build configuration folders in angular.json like
"prod-en": {
  ...
   "outputPath": "dist/en/",
  ...
},
"prod-ru": {
  ...
   "outputPath": "dist/ru/",
  ...
}
  1. Configure docker build file like this to compile app for different languages
FROM node:8 as build-stage
WORKDIR /app
COPY angular-util .
RUN npm install
RUN npm run ng build -- --configuration=prod-en
RUN npm run ng build -- --configuration=prod-ru

FROM nginx
WORKDIR /usr/share/nginx/html
COPY --from=build-stage /app/dist .
COPY nginx.conf /etc/nginx/conf.d/default.conf
  1. Use this nginx.conf to serve app on subdomains (like en.site-name.com, ru.site-name.com), where ru in set $subdomain ru; should be replaced with your default locale
server {
  listen 80;
  set $subdomain ru;
  if ($host ~ ^(\w+)\.) {
    set $subdomain $1;
  }
  location / {
    root /usr/share/nginx/html/$subdomain;
    try_files $uri $uri/ /index.html =404;
  }
}

For more details see here
https://github.com/ivanivanyuk1993/angular-util/tree/master/src/app/util/shared/route-list
https://github.com/ivanivanyuk1993/titans-shoulders-project/tree/master/container-description/ui-container-description

I would like a thumb up for this comment. It may be not perfect, but it still is most helpful post on this topic I found on the web

Hello everyone,

I am using i18n translations for my project. I have doubts in the following area:

  1. Is it possible to generate different xlf source files for different libraries (created using ng generate library libraryName command)?
  2. While using internationalization for select or pluralization , the generated xlf source file creates the trans-unit id for the different alternatives. Is it possible to provide an id via template for different alternatives as well?(as shown in the image below)
    image

Please can you help me with some answers.

@learnersLicense:

  1. You should be able to extract one translation file per project that the cli handles. That being said translations don't work with libraries right now (meaning that someone who consumes your library will not be able to load your translations for that library). It's on the top of our todo list for the next features that we'll implement (with code translations)
  1. I don't think that it is possible. You can name placeholders with special comments: <div i18n>Some value: {{ valueA // i18n(ph="PH_A") }}</div> but I don't think that it works with ICU expressions, @AndrewKushnir ?
    You could make a feature request for that, or maybe add a comment to https://github.com/angular/angular/issues/24080 which seems to be similar (add desc / meaning to ICU expressions)

someone who consumes your library will not be able to load your translations for that library

One way to work around this is:
1) have library extract i18n into xliff & translate
2) ship xliff files with library package

3) consumer also extracts it's own xliff files
4) consumer loads xliff into xml parser. drops any trans-units that originate from node_modules
5) consumer concats it's xliff with library xliff

meaning that someone who consumes your library will not be able to load your translations for that library

Maybe I'm misunderstanding this statement but I know with the translations setup for my companies applications when I build my xlf files they include keys specified in the templates of other projects. One that comes into mind is https://github.com/ng-bootstrap/ng-bootstrap

This doesn't seem possible at the moment:

<my-button i18n-title="@@SHARED_GO_LABEL" [title]="'Go'" [button-style]="'primary'" (click)="navigateToForm()"></my-button>

Within the scope of these changes will this be addressed (or am I doing something wrong)?

@mikejr83

That is possible. You just have to assign the base value of title as title="Go" and not [title]="'Go'"

thank you @ocombe and @ewok-janitor for your answers and suggestions . 👍

@ocombe is there any tentative date by when translations for library might be available?

No date for now. For the first release of ivy we are just trying to have feature parity. We'll work on the new features (including code translations and library support) right after (or actually we'll start working on it before, but it won't be finished when ivy is released in alpha). It'll be available before ivy becomes the default.

Is there already a fix for the xliff files? https://github.com/angular/angular/issues/17506
It's impossible to use the format at all as long as the references are not fixed.

@ocombe Any plans to support route translations?

it's been requested a few times yes, it's not an immediate plan but it's on the list of things to do

Hi, is there any documentation on how to use runtime i18n when ivy is released in beta?

@marcelnem, if you check this URL, all documentation points are pending.

https://is-angular-ivy-ready.firebaseapp.com/#/status

@ocombe great work you are doing at Google now. Angular i18n should have been 'something' like ngx-translate from the start. I was wondering if there will be a migration guide, automated-tool, feature comparison,... to migrate from ngx-translate to Angular i18n style once Angular 8/9 is released?

hi ocombe
Need to check with you regarding this Feature , the one you stated above
Runtime i18n (one bundle for all locales with AOT) - [working on it] >> Is this still under progress , or it out

Could you let me know , any work around , if its still under progress
Thank you

@ocombe you wrote above that the language packages should be loaded by lacy loading. Will it also be possible to load the language packs directly in the index.html? Because we have the case that our application runs over AWS Lambda and the compiled angular files are stored in a S3 bucket. It's actually already a workaround that this works at all, but we can't use lacy loading because Angular can't lacy load the files from another host. Therefore, all files that Angular needs must already be included in the index.html (where we add the S3 host via a script).

@nidhi8953 it's still WIP, it'll be available with ivy, for now it only works inside of google (because we use Closure Compiler internally for the translations). The runtime service that will handle the translations is very much experimental for the outside world. If you want to test a few things, you can look at this example: https://github.com/angular/angular/blob/master/packages/core/test/bundling/hello_world_i18n/index.ts but you should know that the functions are still private for a reason, they will be renamed and changed in the very near future. The current goal is to start working on a solid set of APIs once v8 is out (at the end of the month) and to iterate around this for the whole v8 until v9 is out, at which point the API should be considered stable

@vekunz if we follow our current plans it should be possible yes, since you need to have the translation file loaded at the bootstrap of your application anyway

@ocombe Can we use Ivy (currently 8.0.0-rc.3) and implement i18n using the Angular 7 method of multiple builds? Or do I need to stick with Angular 7 until the i18n APIs for Ivy are released? If possible, I would really love to take advantage of Ivy, while at the same time using the old way of i18n until the new, runtime method is available.

Update: After trying it out, neither ng xi18n extraction (see #https://github.com/angular/angular-cli/issues/14225) nor building w/ i18n have any effect. No .xlf file is exported and no words are translated. But with the enableIvy option set to false in tsconfig.app.json, both work great with version 8.0.0-rc.3. This means I can follow Angular's upgrade path, not lose i18n, gain some of the new benefits like differential loading, and be ready to turn Ivy on once i18n works.

@jacobbowdoin as you found out it doesn't work with ivy on, but it works if it's not activated.
I wanted to make the old extraction/loading system work with ivy, but since it would have just been temporary it wasn't determined as a priority by the team (which is understandable, making mandatory things work first is the priority).

Hi @ocombe, we want to develop the i18n now, so we cannot wait for the runtime-i18n. Would you still recommend to use ngx-translate? Does it make sense to use it with i18n-polyfill? Will using i18n-polyfill make migration to runtime-i18n easier?

If you use ngx-translate, don't use i18n-polyfill. It only makes sense to use it if you use angular i18n for the templates.
ngx-translate is still relevant and is easy to use. You don't have to put all of the infrastructure in place to support multiple build (one per locale).

Hi @ocombe , is there any status update on the:

-Runtime i18n
-Use translation strings outside of a template - #11405

We are currently debating if we should wait for source code translations or use i18n-polyfill (we already started with i18n). We can easily wait a few weeks, so a approx timeline would be appreciated. Thank you very much!

@halilovicedvin as soon as ivy is the default in google apps, we'll start working on the runtime i18n service for external users, so somewhere between soon and v9
I wouldn't count on it until after the summer because people are going to take some days off

@halilovicedvin we're started with i18n with i18n-polyfill some weeks ago and it works great. I hope that runtime-i18n will be used the same way as i18n-polyfill

@vekunz I was hoping too that if we use ngx-translate with i18n-polyfill, we will be able to migrate easier to runtime-i18n but after the comment from @ocombe (https://github.com/angular/angular/issues/16477#issuecomment-498239301) I am not sure if the additional effort to setup the polyfill is justified. Maybe we wull just use ngx-translate alone.

@vekunz what is your experience setting it up?

@marcelnem you cannot use ngx-translate with i18n-polyfill. i18n-polyfill is only for use with angular-i18n.

The setup of i18n-polyfill was indeed very easy. Even the documentation is not that exactly correct, I figured it out very fast what to change.

@vekunz I understand now, thank you. I am not sure what the purpose of the i18n-polyfill is. Do you still have to build the app multiple times and deploy it multiple times under http://myapp/en, http://myapp/de, http://myapp/fr,... as with official angular i18n?

@marcelnem yes, you need multiple build with i18n-polyfill also. The purpose is that with angular-i18n you can use translations currently only inside of html templates and not inside your typescript code. i18n-polyfill extends angular-i18n to use translations inside you typescript code as well.
With Angular 9 (coming in fall) angular-i18n will support translations inside typescript also, but in the meantime we need i18n-polyfill for this.

@vekunz can you go a bit more in detail about this: "Even the documentation is not that exactly correct, I figured it out very fast what to change." I am probably look into i18n-polyfill next week, so any info would be apreciated. Thx

@halilovicedvin @marcelnem I created a pastebin doc where I describe it, because it is not the main topic of this GitHub Issue https://pastebin.com/Xib6X6E9

@ocombe Using xi18n tool, can I restrict the input path to only src folder (to generate the translations) rather than entire project/repository?

@ocombe does Ivy support multiple locales with Angular 8 (just the locale definition, not language file; for example for date pipes)? Because an other team uses Angular currently with ngx-translate, but one third party component needs the correct locale. One option would be to use the JIT-compiler in prod mode, but this is not very nice. But also they can't compile a new bundle for every language, because this would be very to much.

@vekunz no you can't set multiple locales, you need to set the locale for each compiled bundle (it can be set in the cli config file)
I know it's not what you wanted to hear, but that's how it is for now

@ocombe Can you please tell something, I know that Angular's team don't identify it as a problem, but do you think Angular will allow us in the foreseeable future to change the language in runtime without reloading the app, so having the translation in one single bundle and having the possibility to load the right translations and bind it with the text literals?

Having one bundle yes, but the translations will have at be loaded at boostrap (when the app loads). With the existing architecture it would be very complicated to "hot" reload the translations without reloading the components that already use the translations.
I'm not saying that this is impossible, but I don't see it happening in the foreseeable future unfortunately.

Thanks @ocombe for the quick response :) Keep up the good work :+1:

There was somewhere a presentation of @ocombe from some angular conference (I think AngularConnect) where he talked about i18n and Ivy, and there he described it very good, why this is so complicated. I can try to find the video.

For people waiting for runtime i18n with ivy the current plan for v9 is to have translations working with ivy but only as a build step (like it is right now with view engine). This means that it's still going to be 1 build / locale for now, and there won't be code translations (only template translations).

Bummer. Well, for what it is worth, thanks for your hard work!

@ocombe will you still be maintaining the polyfill for runtime code translations?

if it breaks yes, I won't be adding new stuff to it though

It kind of sucks that i18n has been a 2nd class citizen for so long... Not everyone works in a native English locale environment. ):

Well I agree, I'm trying to find some companies to sponsor me so that I can develop new powerful i18n solutions for Angular (I've got a ton of ideas).
If you think about people who would be interested, let me know on Twitter (@ocombe) or by email ([email protected]) 🙂

@ocombe I would like to thank you for your work also. 💚 It's a bit surprising news that you have to leave the team. As you said I had to ..., it guides me to ask you directly what was the main reason. I hate those indirect hints and guesswork, so that's why such a direct question to you.

I was an external contractor working with the Angular team and not a full time employee of Google and as such my contract can end at any point depending on what the team needs.
They are recruiting new people internally to help with the project and I'm confident that they will find the right people to help with i18n and other topics, so you don't have to worry about the future of Angular :visage_légèrement_souriant: it's just a temporary setback

@ocombe Thank you for your explanation.

Can anyone tell me how can I use i18n (i18n-polyfill) outside the class like enums or const arrays or something like .model.ts files?

For constants, I still put them in a class. I don't know of any alternative :/

@ocombe Thanks so much for all your hard work with i18n for Angular with ngx-translate, i18npolyfill and with the Angular team.
We use your work daily to provide translations to our users, as is required by any non-trivial application.
Best of luck in what you do moving forward.

For constants, I still put them in a class. I don't know of any alternative :/

Hmm.. if I move them to class then I need to make the variable as static to be used. But I cannot use i18n to a static variable.

export class Example {
constructor (private i18n: I18n) {}
static variable = i18n('text'); // I cannot use i18n here as it is non static of class Example
}

Sad news... this "weakens" Angular... Like the others say, it remains only the big thanks to @ocombe for the great work, best of luck!

I'm curious, what are the disadvantages of using ngx-translate? It seems it's capable of exactly the functionality people are looking for

I would say that the disadvantages are the following:

  • increases the bundle size (external lib + translations as external files instead of replacing the code at build time)
  • not official (if I die then the lib gets discontinued, and not the same level of support)
  • doesn't support xliff/xmb (but supports json and other formats via plugins, and one could make an xliff/xmb plugin to support it)
  • might have some buggy behaviors when lazy loading/splitting the translations (I never got to fix that)
  • syntax is more complicated compared to the official implementation
  • performance (initial loading of the translations can make the text disappear for 1s, and more memory pressure because I have to monitor the content at runtime to see if something changed)

That being said it seems to be good enough for a lot of people 🙂

It's curious how angular promotes and invests in accessibility but does not include languages in that package. It really feels that this is a decision taken from a monolingual environment.

Coming from an environment where we usually have to serve 3-4 languages interchangeably I've been patiently awaiting release of this feature since it's announcement with its clear advantages over using an external library. With this news I'll have to reconsider our strategy for managing translations completely.

@ocombe No chance that Google hires you not as a contractor?😉

@DmitryEfimenko We are using ngx-translate currently and are quite happy with it.

@ocombe what is the chance that Google accepts this feature from external developer/community? I think we're waiting toooooo long.

if you are serious with it and want to spend time working on it, then I'd say that the chances are high that they'd accept help to work on this feature

if you are serious with it and want to spend time working on it, then I'd say that the chances are high that they'd accept help to work on this feature

@ocombe @IgorMinar I'd like to provide some volunteer work for Ivy i18n, please let me know if there are some chances.

if you are serious with it and want to spend time working on it, then I'd say that the chances are high that they'd accept help to work on this feature

I'm willing to contribute but I absolutely don't know the scope and complexity of the tasks. Can we take the list in the original message as our specification/requirements?

No, this list is now obsolete.
I'll let the team know that you two are interested so that we can see how to organize this.

@ocombe I think it's more than 2 of us.

What we need from the Angular teams are

  • a requirements list/some specification
  • rough complexity estimation
  • 1-2 mentors for communication

with that community could organize development and split tasks

There is what I am aware of on https://hackmd.io/UfFN_wyVT-Ob1p70nA3N_Q?view

@fetis It may not be a good idea to split the work too much, communication and context sharing also cost heavily, especially for some core works having high chance of conflicts.

Still surprised XLIFF is listed as a pro (or rather, lack thereof for ngx-translate is a con). Google Translate and other Google services seem to be using ARB files, which is a JSON representation of translation strings. For example, we built our mobile apps with Flutter/Dart, where the INTL is implemented with ARB files. It'd be nice if the Angular team, when looking this over, takes this into account for better inter-op with other items in the Google ecosystem.

It may not be a good idea to split the work too much, communication and context sharing also cost heavily, especially for some core works having high chance of conflicts.

I agree but I don't think this whole can be delivered by one person in a reasonable time. The scope is too huge

It may not be a good idea to split the work too much, communication and context sharing also cost heavily, especially for some core works having high chance of conflicts.

I agree but I don't think this whole can be delivered by one person in a reasonable time. The scope is too huge

@fetis I can work with you. We really want to use angular i18n in our projects, but it's very limited.

I'll let the team know that you two are interested so that we can see how to organize this.

@ocombe any feedback from the Angular team?

I've let them know and they seemed interested, but they need to come up with a concrete plan for all of that before they can accept external help (otherwise you're probably not going to work on what is needed).
@petebacondarwin will take over from now on

Hi @ocombe, I was going through the comments and I roughly understood that still there is no provision to create dynamic IDs for i18n tag while we use them in *ngFor. Is there any other option or workaround? Or I have to go with ngx-translate only.

@swapnilvaidankar I don't think that there is a workaround, no

@swapnilvaidankar - can you explain what you mean by this?

create dynamic IDs for i18n tag while we use them in *ngFor

As we know, to translate the static text into any other language we have to use i18n attribute in the HTML element tag as below,

<h1 i18n = "Card Header | Title for the under construction card@@constructionheader">Under Construction</h1>

which generates the xlf file snippet as below and we can set target for any language. Here I have translated for French as below,

  <trans-unit id="constructionheader" datatype="html">
    <source>Under Construction</source>
    <target>En construction</target>
    <context-group purpose="location">
      <context context-type="sourcefile">src/app/app.component.html</context>
      <context context-type="linenumber">3</context>
    </context-group>
    <note priority="1" from="description"> Title for the under construction card</note>
    <note priority="1" from="meaning">Card Header </note>
  </trans-unit>

But in case of dropdown list it seems difficult to use i18n attribute.
For example, if I want to show the list of products such as Business card, flyers and Booklets into dropdown list or simple list how can I generate the dynamic id for the tag hence I can translate the product names into French or any other language.

I have tried this way,

which generates the xlf file snippet as below and not sure how to use this to translate the product name into other languages using tag

  <trans-unit id="product" datatype="html">
    <source><x id="INTERPOLATION" equiv-text="{{ product }}"/></source>
    <context-group purpose="location">
      <context context-type="sourcefile">src/app/product/product.component.html</context>
      <context context-type="linenumber">6</context>
    </context-group>
    <note priority="1" from="description"> product name from List</note>
    <note priority="1" from="meaning">product name </note>
  </trans-unit>

The problem here, if you can see the id in tag is 'product' only. However I was expecting the ids should be generated dynamically as per the list of products are going to be available into dropdown list.

Not sure how to achieve this whenever dealing with dynamic content or list of content.

Sorry for the extensive explanation.
I hope you have understood the issue here.

Thanks,
Swapnil

Can you open an issue for that please? It's not really the topic here and if anyone else is looking for the same thing it will be easier to find it

@swapnilvaidankar i18n attributes are meant for static text translation not dynamic content. In your example "product"s are either coming from your source code (are defined in your ts file) and you need to use ngx-translate (or have translated product names directly in the ts file), or are coming from an Http request then translated product names should be provided by your backend.

I don't think we need a new issue for that. It's just request for run-time translations in TS files which was already requested many times.

@swapnilvaidankar if number of options is limited and you already know it, you can create a component with simple ngSwitch which renders the text. We use this workaround, works like a charm.

@fetis - the trouble is that it is very easy for these general issues to be side-tracked into discussions about specific things. Creating a new issue provides a new thread to continue that discussion without distracting this one.

@fetis Yeah, this issue I have seen many times many places however I didn't find any proper solution. I came across ngSwitch also but not suitable solution in my case. However thanks for the workaround.

@ocombe I believe I need to post this as an issue some where else to discuss the same rather than here. 👍

Thank you all for the responses.

@petebacondarwin @swapnilvaidankar here's the issue https://github.com/angular/angular/issues/11405 you're looking for
since 2.0.0-rc.6 (!) btw

Hello @ocombe , is this issue still up to date? Seems like Ivy is going to be the default on Angular 9 so I wonder what the status of i18n is? Could you please estimate when it could be production ready? With Angular 9, 10, 11? If not with Angular 9, will Angular 9 (and Ivy) ship with no i18n or will it use the old i18n?

Some more info about the current state can be found in this (https://github.com/angular/angular/issues/11405) issue. Comments worth reading in this issue about the current state:

Also this is worth checking out.

image

Although we are flipping the switch in v9 so that the default is to use ivy, we expect that there may be a number of scenarios that are not fully working, and that those projects would stick with view-engine for now.
We are working to get i18n up and running for the v9.0.0 release but it will be tight.

What current status on "Runtime i18n (one bundle for all locales)"?

@Ivajkin - sorry that this issue is not being kept up to date.

"Runtime i18n" is a commonly asked for feature but it can mean different things to different people.
In the new i18n $localize approach, it will be possible to do the actual translation at runtime.

Runtime can actually be rather complicated if you are not just translating all possible messages before the Angular application bootstraps. If you are doing this then the new approach to compile time translation could well be what you need.

In the new i18n the translation happens at the very end of your build pipeline - not in the Angular compiler - this means that you should be able to provide untranslated messages in libraries etc and only do the translation when you build the final application.

This is all in the works for v9.0.0.

Check out https://github.com/angular/angular/tree/master/packages/localize to see where we are.

@petebacondarwin Would you mind elaborating a bit on the new compile time translation? Will this allow us to build a single bundle (with AOT) that works for all locales?

In the new approach, instead of doing translation inside the Angular compiler we simple "tag" the messages that need to be translated via a global $localize templated string tag handler. These tagged strings survive all manner of bundling and minification, so that at the end of your build pipeline they are still there and discoverable. These files could be the bundle of your library that you send to some other team to include in their application!

We now have a couple of options:

a) run a tool that statically identifies these tagged messages and replaces them with translations. This effectively removes the $localize references from the JavaScript and leaves you with a minimal code bundle for distribution. This "compile time inlining" tool can take a number of translations and generate a copy of your bundle for each language you are translating. Since it can be run at the very end of your build pipeline it avoids having to run other aspects of your build for every language you support.

b) allow the $localize tags to end up in the code that is run in the browser, and use an implementation of $localize to translate the messages at runtime. The downside of this approach is that the payload to the browser is larger since it must contain the $localize calls but also the $localize translation implementation. Also you must send the translations themselves to the browser. One benefit of this approach might be to support lazy loading of translations at runtime. But it is arguable that doing the translation on the http server (or build server) makes a more efficient runtime experience.

Runtime option b) please. We could load translations as JSON files and switch languages at runtime as we currently do it with ngx-translate.

Thanks for the explanation. I understand that the a) approach is more "Angular" but the great advantage of the b) approach (and lazy loading in general) is also the ability to dynamically define / change translations by users (modified translations for apps could be used immediately). If I understand it correctly, any small change in translation in approach a) would mean a new rebuild.

This is the same advantage as switch from statically generated pages with predefined Angular components to user-generated templates contains the angular components defined by the programmer as desired by the user (the template defined in this way would be also loaded from the database...)

You may also have thought about the possibility that by default, the a) approach would be used when loading. If a runtime translation request arose (for example, the backend will start sending newer translations), the marked blocks (containing static text until now) would begin to be crawled and replaced dynamically, like in the b) approach. So b) would only be activated if required and all translatable parts will be prepared according to procedure a). I understand that such an approach would be more burdensome than the b) approach itself and is certainly not directly feasible in this way, but this would be closer to the actual needs of users.

To the options you listed, I am willing to sacrifice about 25% of the application performance in certain cases to achieve such dynamic functionality (of course I would not use this dynamic approach everywhere). So if the AOT localized template were rendered in 0.4 seconds, in the case of a dynamic template if it was generated in 0.5 seconds, I would still consider it acceptable in apps where I need such immediate responses to translation change.

@demisx both approaches will be available with v9, but only option a) will be fully supported at first (for retrocompatibility), new things might be developed for option b) before it is fully endorsed by the Angular team.
My library Locl will provide a few helpers for option b) when v9 is released so that anyone can use it, until the Angular team bridges that gap

Be aware that such runtime translation would not be "reactive" in the sense that once a component has been rendered it would not be possible to change its text dynamically, even if a new translation were loaded.

Translated messages are static with respect to $localize tagged strings. So the component would need to be re-rendered. And depending upon the caching of templates in IVY it might be that a re-rendering is not even enough.

This is one of the reasons why runtime translation is tricky to implement since its behaviour would not necessarily be intuitive.

Regarding the hybrid approach of starting with a static translation in the build and then adding runtime translation later. This could be feasible if the compile time inlining did not remove the $localize tags but just updated the templated string literal parts. Though, this would result in the compile time cost plus the extra bundle size cost.

Running ng xi18n on Angular 9 RC1 returns "We are sorry but i18n is not yet implemented in Ivy", but the changelog indicates that there is _some_ i18n support implemented now. I assume the translation files need to be manually updated for now?

@neil-119 Currently extraction is not supported in ivy-mode. You still need to disable ivy to run the extraction. But then you can re-enable it to consume the extracted translation files.

I hope it is planned to include extraction in the final v9 release.

@neil-119 Angular CLI should automatically use VE for extraction. You shouldn't need to do anything for that to work. We also test that so I'm surprised it's broken. Can you open an issue with a repro please?

Currently extraction is not supported in ivy-mode.

or no, it's a show stopper. Currently, we have an automated process with strings extraction. How can we migrate to Ivy, if we can't extract translations automatically?
Manipulate sconfig.json every time? This doesn't sound good for me.

@fetis - I was incorrect. If you are using CLI then calling ng xi18n should work as expected, even when ivy is enabled.

@petebacondarwin thanks. I'm going to try out Ivy in our current projects, so hope I'll confirm this soon

Hello, I tried to use in my component (angular 9.0.0-rc.1)

$localize `some string to localize`;

found as doc in the sourcecode of @angular/localize/init.

When I try to build as usual for my language I get this error
No translation found for "4145296873012977836" ("some string to localize").

How can I provide a translation for that string?
What I expect is that ng xi18n will generate the .xlf file with also this text from the component code. Is it right or I'm missing something?

Hi @Ks89 - extracting messages from application code (rather than templates) is not supported for v9.
But you can workaround that if you are sneaky. The 4145296873012977836 is the id of the message so if you provide a translation in your translation file with this ID it will be used when translating.

@petebacondarwin when this feature will added to Angular?
I think that it's really important to make runtime translations in component really useful.

When I send my .xlf file to a translator I expect to add all strings quickly and then apply the result to the app very easily.

thanks for the answer

I would expect it in 9.1

If we have a way to force the whole app rerender no matter what ChangeDetectionStrategy is for every component, then it's so easy to solve those dynamic issues.

@petebacondarwin Angular 9 is now released with the new $localize tag function, but without extraction of the messages. You said before that we could expect this in Angular 9.1. Is this forecast still valid, and can we expect the $localize API to be stable?

You can extract translations from templates.
If you want to use $localize in your code as well, you should take a look at Locl: https://github.com/loclapp/locl/
@locl/cli will let you extract from code & templates

@vekunz - the forecast is still valid. Moreover, as @ocombe points out, the current CLI translation extraction mechanism works just fine for any translation that is within an Angular template (i.e. stuff that is marked by the i18n tags). The only thing you are not able to extract using the core tools right now are calls to $localize within your own code (e.g. in a service or component).

The $localize call itself is a stable API.

The tooling that does translations and extraction (specifically at compile time) is still non-public. But this is not a concern unless you are planning on building your own tooling around it (like @ocombe is doing at Locl!).

Thank you @petebacondarwin, with this, we could duplicate the texts from code into a "hidden" component template for extraction. Then the extraction and the translation both should work, shouldn't it?

@ocombe With the forecast that extraction works with Angular 9.1, our manager wouldn't pay for your solution. Especially because we don't need live switching of languages and translated routes.

we could duplicate the texts from code into a "hidden" component template for extraction

Yes indeed, this workaround would work for now.

I'm confused: Will the runtime translation also be possible in 9.1? Or just the extracting outside of templates? Or none of these?

For me the runtime translations would be a killer feature. To deploy multiple bundles and forcing the user to reload the whole page is not a good usability I think.

@JustDoItSascha
I've created a simple demo, which demonstrate runtime translation.
https://stackblitz.com/edit/ivy-vjqzd9?file=src%2Fapp%2Fapp.component.ts

Hi! I'm trying to call loadTranslations in main.ts because strings are translated while JavaScript parses imports, but that's not enough.

main.ts imports AppModule that imports AppComponent (where I'm using $localize).

To make it work I'm doing:

loadTranslations(......);
import('./app/app.module').then(m => platformBrowserDynamic(). bootstrapModule(m.AppModule);

Now this works but causes Angular's "complier.js" bundle to be included in the vendor bundle.

Any way to avoid that? Thanks

Currently, loadTranslations needs to be called before the application starts, so it can be done in polyfills.ts. And if you want to load an other set of translations, you then have to reload the page. If you want to understand a bit more why, I wrote https://blog.ninja-squad.com/2019/12/10/angular-localize/ to explain it.

Currently, loadTranslations needs to be called before the application starts, so it can be done in polyfills.ts.

It's even worse than that, it needs to be called before any module file is imported, that's why it works if you put it in polyfills.ts (which is executed before the main app file), but if you want to use it in your "main" file then you need to use a dynamic import(...) for the module

@vekunz it's a good reason to not use my lib for now 😊 that being said Locl is not just about extraction, I intend to add a lot of other tools to simplify i18n

Is there any intention of implementing runtime i18n in Angular ever? We've been expecting the feature for almost three years and now Ivy's here and it's still only half-baked.

Is there any intention of implementing runtime i18n in Angular ever? We've been expecting the feature for almost three years and now Ivy's here and it's still only half-baked.

My understanding is that Ivy, in many ways, is an enabler for things to come. Unsurprising that the i18n needle did move incredibly with the release of Ivy, but it should unleash the potential for big changes down the road. That's been my read of it, and my hope, anyway.

@Karasuni - I think we need to clarify what runtime translation actually means for the core Angular framework because there is quite a bit of confusion about it.

The changes that we made for v9 involve the $localize based translation. The primary aim of this was to decouple translation from the Angular compiler, so that it enables a number of nice improvements:

The first of this, which is immediately available to all users of v9, is to speed up generation of translated applications. Previously, the entire build pipeline had to be run for each language that you wanted to translate your app into. Now the main compilation of your application only has to be run one and the final translation process, which is significantly shorter is run for each language on the output of the build. To support this there is the new @angular/localize package, changes inside the Angular compiler and a whole load of work inside the Angular CLI to make this as seamless and transparent as possible

Secondly, since the $localize tags can be left in the distributed code, it is now also possible to do the translation in the browser (at runtime, rather than at compile time). This is what we mean in the core Angular framework as runtime translation. But please not that the final outcome of this is effectively the same as translation at compile time. The translation happens only once; if you want to change the language at runtime then you must restart the whole application (e.g. via a reload). This has the benefit of allowing the project to deploy a single distributable with numerous translation files, which is helpful in a small number of use cases where you do not want to generate all the different translations up front. There are some tricky issues around loading the translations early enough as pointed out by @ocombe and others here. You could consider https://www.locl.app/ for more help with doing this.

Note that this "runtime" translation can also be used on lazy loaded routes so it might be feasible to have different routes in different languages depending upon how you set things up.

Since there is not a single approach to this loading of translations that works for all scenarios, we have not baked this into the CLI or provided stable public APIs to support this yet. Once we get a better understanding of the use cases then we might be able to add more support for this. In the meantime things like Locl might help if you don't want to venture into working it out for yourself.

Finally, note that dynamic changing of translated strings at runtime is specifically not supported (by design) by the core Angular framework. Hooking the translated strings into Angular's change detection system would put too much strain on most applications and ruin performance. From my interactions with the community I have seen hardly any real world scenarios where this is actually needed over and above restarting the application on language change. If this is a requirement for your application then you could achieve it by using a custom built pipe on your strings in templates that pulls in translations, and maybe even calls $localize on the fly to translate but it does not look like this would be very performant. Otherwise you could consider a more dynamic approach like https://netbasal.gitbook.io/transloco/.


The main changes coming in the next minor version of Angular will be improved translation extraction, which will be able to identify and extract localized strings from TS code - currently the CLI extraction only handles localized strings in templates.

Changes to improve runtime translation, as described above, would not appear until after 9.1 at the earliest.

Finally, note that dynamic changing of translated strings at runtime is specifically not supported (by design) by the core Angular framework. Hooking the translated strings into Angular's change detection system would put too much strain on most applications and ruin performance. From my interactions with the community I have seen hardly any real world scenarios where this is actually needed over and above restarting the application on language change.

I might be mistaken but in this thread alone many people expressly showed interest in the ability to change the language live, at runtime, without having to rebuild or reload the application. Or does everyone here have a different definition of runtime translation?

I do not want to reload an application just to switch a language. For example when a user is on a page with a form a full page reload for a switch in translation will be jarring to the user.

Just to be clear. What I meant to say is that lots of people have come up to me to say that they absolutely need live language changing in their application. But when you dig into the reasons it turns out that they don't. I am not saying that there are no scenarios that require this, but in my experience over the last year, I have come across very few.

Question: why would a user need to switch languages when the go to a particular form on your app?

I don't think that live switching is necessary also. How often do you change the language of a website? Usually one time, at maximum. And for this one time, a page reload is not that critical. As @petebacondarwin said, almost all scenarios for live switching are not relevant real-world scenarios but only "nice to have."

Or does everyone here have a different definition of runtime translation?

I absolutely need runtime translations. Our customers need to be able to edit and update translations in the field, not just on the build server. So, runtime, as opposed to compile time.

Actual switching of languages after page load is a nice-to-have.

Just to be clear. What I meant to say is that lots of people have come up to me to say that they absolutely need live language changing in their application. But when you dig into the reasons it turns out that they don't. I am not saying that there are no scenarios that require this, but in my experience over the last year, I have come across very few.

Question: why would a user need to switch languages when the go to a particular form on your app?

You might be right that it not a solid requirement. I might attempt deploying translations on load but it will completely transform the user experience of the applications that are currently able to switch language dynamically - without reload or changing position in the page - with an external library. Translations has been a heated topic for a very long time.

I do have an important question: Can translation files be loaded asynchronously? All my translations are stored in a database as being able to update them without a rebuild is important.

yes they can be loaded asynchronously, but you need to delay the start of your application until they have been loaded

Just to be clear. What I meant to say is that lots of people have come up to me to say that they absolutely need live language changing in their application. But when you dig into the reasons it turns out that they don't. I am not saying that there are no scenarios that require this, but in my experience over the last year, I have come across very few.
Question: why would a user need to switch languages when the go to a particular form on your app?

You might be right that it not a solid requirement. I might attempt deploying translations on load but it will completely transform the user experience of the applications that are currently able to switch language dynamically - without reload or changing position in the page - with an external library. Translations has been a heated topic for a very long time.

Technically you can reload the entire app and still keep the user where he was.
You "just" need to have a state-driven app (with ngxs, ngrx, or any other state management library) which is stored somewhere and retrieved at startup.

The only trick would be to keep scroll position but that's feasable too.

@petebacondarwin I have to say that I agree with you. I don't know real end-users (except testers in dev phase) who are switching an app permanently between languages when using it. Sure, they do it probably at the beginning if they open it in a different one somehow, but later, it's a rare case.

Or does everyone here have a different definition of runtime translation?

I absolutely need runtime translations. Our customers need to be able to edit and update translations in the field, not just on the build server. So, runtime, as opposed to compile time.

Actual switching of languages after page load is a nice-to-have.

I'm not sure, what your customers are doing, but "editing of translations live in the production website" doesn't sound like a common scenario.

I don't see changing language live (_without page reload_) to be such a deal breaker.
Changing a language for a user happens only once;

Think about it, how many times you have changed your phone language ? probably once or you just rolled with the default language.

Watching for language changes in order to do live change without page reload brings a lot of performance penalty for something that is barely used for the lifetime of a user.

Ultimately, in comes down to 3 things for me;

  1. Extract translations from templates and TS files.

    • Update source lang asset.

    • Update translation as well (_if I have multiple languages, fr, en, de... I want all of them to be updated with new translations keys and removed ones._)

  2. One build for all the translations (_Having 1 build for each translations is fine as well, as long as it doesn't multiple the build time._)
  3. Getting available languages and change the language with reload.

@Karasuni
You can fetch translations async and only then load the angular app.
See my comment above on how to load the app.module asynchronous using import(...).

personally I use Wikipedia to figure out what the title of a movie that I know was "translated" to in another language.

in this day and age being bilingual or trilingual is more than commonplace (aside from within the US, no harm meant).

the user might want to live switch languages it's completely plausible. the Wikipedia example is a positive result of having enabled this, I don't see why we should stifle other potential uses before they live to see the light of day under the pretext of performance.

even ocombe's ngx-translate which has to be the tantamount example for you guys of "poor performance translations" ran perfectly fast enough for the everyday user.

I personally am trilingual and I can't settle on using one language : all languages are beautiful to me

with all that said I cannot agree with this :

Think about it, how many times you have changed your phone language ? probably once or you just rolled with the default language.

Wikipedia is the worst example of this because the different languages of an article are actually independent articles. Normally you don't need different languages of the exact same site. Even if you work quadrilingual.
And if you actually need live switching, you can use either the workaround with the custom translation pipe, which @petebacondarwin mentioned or the new tool from @ocombe.

OK, so I don't think that this is really the best place to have this discussion. I am concerned that (while have all been very reasonable so far) we might slip into negative discussion. I'm afraid that for the foreseeable future the Angular framework will not provide a live language switching solution out of the box.

I feel that the value of this issue has run its course. I have moved the open issues and PRs that are linked in the description of this issue to https://github.com/angular/angular/milestone/101 and I am going to close and lock this PR.

If you have new issues of feature requests then please do open up a new issue and tag me in it.

Was this page helpful?
0 / 5 - 0 ratings