Skip to content

i18n support in Angular libraries #17140

Open

Description

@multimike77

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • xi18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

No. Related functionaliy only available with new i18n capabilities of angular 9.

Description

I want to use ng xi18n command to extract messages for i18n tags which are part of a library project which is part of a monrepo setup created by the cli. According to docs at

https://angular.io/cli/xi18n this is supposed to be possible

ng xi18n <project>
<project> The name of the project to build. Can be an application or a library.

🔬 Minimal Reproduction

  1. create project: ng new lib-i18n
  2. add localize: ng add @angular/localize
  3. generate library: ng g library my-lib
  4. add i18n attribute in my-lib.component.ts
    <p i18n>
      my-lib works!
    </p>
    
  5. run ng xi18n my-lib: Result will be
    An unhandled exception occurred: Project 'my-lib' does not support the 'extract-i18n' target.
    After adding corresponding extract-i18n target in angular.json, error output as below.

I created a minimal demo project which incorporates the scenario describe above. It is located here:
https://github.com/multimike77/lib-i18n-issue

Checkout and run npm install. Then run ng xi18n my-lib and it should produce error as below.

🔥 Exception or Error


An unhandled exception occurred: The "path" argument must be of type string. Received undefined

[error] TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at validateString (internal/validators.js:117:11)
    at Object.resolve (path.js:980:7)
    at Object.getCommonConfig (/Users/.../lib-i18n/node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js:390:24)
    at /Users/.../lib-i18n/node_modules/@angular-devkit/build-angular/src/extract-i18n/index.js:91:27
    at generateWebpackConfig (/Users/.../lib-i18n/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:62:22)
    at async Object.generateBrowserWebpackConfigFromContext (/Users/.../lib-i18n/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:137:20)
    at async execute (/Users/.../lib-i18n/node_modules/@angular-devkit/build-angular/src/extract-i18n/index.js:73:24)

🌍 Your Environment


Angular CLI: 9.0.4
Node: 12.16.1
OS: darwin x64

Angular: 9.0.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.900.4
@angular-devkit/build-angular      0.900.4
@angular-devkit/build-ng-packagr   0.900.4
@angular-devkit/build-optimizer    0.900.4
@angular-devkit/build-webpack      0.900.4
@angular-devkit/core               9.0.4
@angular-devkit/schematics         9.0.4
@ngtools/webpack                   9.0.4
@schematics/angular                9.0.4
@schematics/update                 0.900.4
ng-packagr                         9.0.2
rxjs                               6.5.4
typescript                         3.7.5
webpack                            4.41.2

Anything else relevant?

Activity

  1. added this to the Backlog milestone on Mar 3, 2020
  2. alan-agius4 commented on Mar 3, 2020

    @alan-agius4
    Collaborator

    Hi @multimike77, thanks for reporting this. The docs seems to be incorrect as i18n extraction is only supported at application level.

  3. multimike77 commented on Mar 3, 2020

    @multimike77
    Author

    Thanks, I thought already that it could be like this. Then I will adjust my expectations for now.
    Are there any plans to support use cases as this one in a future version?

    Overall scenrio would be like that:

    • Library provides its own xlf files containing the translations for text used in the library components
    • Consuming applications can use the translations when creating localized builds

    From what I understood from the docs around i18n and ivy in Angular 9, i18n tags are extracted when used in an application. But like this, every application which uses the library will need to provide own translations for the texts used in the library components. This is of course not ideal in regards to reusability.

  4. alan-agius4 commented on Mar 3, 2020

    @alan-agius4
    Collaborator

    @clydin would know more about this topic.

    But like this, every application which uses the library will need to provide own translations for the texts used in the library components. This is of course not ideal in regards to re usability.

    I think there are two sides of this, you can also say that the library author shouldn't be responsible for the translations themselves, but only provide a way to localise the library.

    Though I do understand that this feature might be useful in some cases.

  5. petebacondarwin commented on Mar 3, 2020

    @petebacondarwin
    Contributor

    In the next few weeks (hopefully) I will be working on new translation extraction tooling that understands the new $localize calls. Some of the goals will be to support libraries better. Some ideas:

    • ability to filter the generated translation files to only include translations from specified sets of sources (i.e. not libraries).
    • ability to merge more than one translation file together at the point where we localize an application, so that a library author could provide translation if desired
  6. multimike77 commented on Mar 3, 2020

    @multimike77
    Author

    I think there are two sides of this, you can also say that the library author shouldn't be responsible for the translations themselves, but only provide a way to localise the library.

    Though I do understand that this feature might be useful in some cases.
    Yes of course, that's also a valid point. Any solution should ideally support either scenario of already shipping with translations or only providing support for translations.

    In our case it's like several shared components and libraries which are used in multiple applications created by different teams throughout the company. The texts and translations for the library components should only be done once and be the same across the applications.

    In the next few weeks (hopefully) I will be working on new translation extraction tooling that understands the new $localize calls. Some of the goals will be to support libraries better.

    This sounds promising @petebacondarwin !

  7. meriturva commented on Apr 23, 2020

    @meriturva

    @petebacondarwin just to know about timings, are we going to see library extraction tool for angular 10 or before?

  8. petebacondarwin commented on Apr 24, 2020

    @petebacondarwin
    Contributor

    That's my plan! But it will be tight.

  9. michaelhunziker commented on May 6, 2020

    @michaelhunziker

    In the next few weeks (hopefully) I will be working on new translation extraction tooling that understands the new $localize calls. Some of the goals will be to support libraries better.

    @petebacondarwin: Is there a way to track the progress for these features?

  10. petebacondarwin commented on May 6, 2020

    @petebacondarwin
    Contributor

    @michaelhunziker - I have not made much progress. You can follow the various PRs that are in flight can be seen at https://github.com/angular/angular/pulls?q=is%3Apr+is%3Aopen+label%3A%22comp%3A+i18n%22+

  11. 32 remaining items

  12. PowerKiKi commented on Feb 16, 2023

    @PowerKiKi
    Contributor

    We also use import '@angular/localize/init'; in our library. And we mark strings to be localized with i18n attribute or $localize() function in the library. Then our app will extract all strings, both from the app itself and the library. This has been working well for us for many months now.

  13. meriturva commented on Feb 16, 2023

    @meriturva

    Here is an old discussion about library (APF format) and i18n: angular/angular#38366 (comment)

    Basically, on my teams, we have more than 100 library projects with translations packed inside plus a schematic that just merge strings from libraries used to xlif file produced by the final app. Just a custom way to make it possible to distribute translations near the library. Another approach is the one chosen by Kendo UI, which just has a big library with all strings from all components plus a script that merge strings on xlif.

    What we would like to expect is to have

    1. a way to extract only strings from one library (now we have a custom script that splits the whole extraction to make a single group of strings and packs them to the correct library to distribute)
    2. a way to indicate translations into library APF format (maybe package.json)
    3. a way to read translations from the library and merge them to the final xlif app file

    I mean, it is something that we do every day with a custom "build pipeline" but I guess a goal is to propose an official approach to cover this need, mainly for small libraries and not-so-big teams.

    My two cents.

  14. PowerKiKi commented on Feb 16, 2023

    @PowerKiKi
    Contributor

    a way to read translations from the library and merge them to the final xlif app file

    Pretty sure this is solved already, because it turns out that angular.json property projects.my-project.i18n.locales.my-locale can take a string or an array of strings. If you supply multiples paths to xliff files, those will be "merged" when compiling the localized versions of the bundles.

    So basically something like that:

    {
        "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
        "projects": {
            // ... other things here...
            "my-project": {
                "i18n": {
                    "locales": {
                        "en": [
                            "node_modules/my-library/i18n/messages.en.xlf",
                            "client/i18n/messages.en.xlf"
                        ],
                        "es": [
                            "node_modules/my-library/i18n/messages.es.xlf",
                            "client/i18n/messages.es.xlf"
                        ]
                    }
                }
            }
        }
    }
  15. meriturva commented on Feb 16, 2023

    @meriturva

    Yes @PowerKiKi locale now supports merging multiple xlif files on angular.json, the main problem is extraction and packing them

    Thanks for the tip!

  16. gzf6 commented on May 31, 2024

    @gzf6

    I think we can create a new playground app for each library and perform extraction operations there

  17. meriturva commented on May 31, 2024

    @meriturva

    I think we can create a new playground app for each library and perform extraction operations there

    I have a project with 180 libraries! I can't follow that approach.

  18. magioloro commented on Dec 13, 2024

    @magioloro

    Do you think you could add a library paragraph in Angular documentation (https://angular.io/guide/i18n) ?

    I have a workspace with one library and one project. I just spend two hours to finally found that I just needed to apply angular/angular#29536 (comment) : add in package.json > projects > my-lib > architect :

            "extract-i18n": {
              "builder": "@angular-devkit/build-angular:extract-i18n",
              "options": {
                "browserTarget": "angular-i18n:build"
              }
            },
    

    to generate with ng extract-i18n a single messages.xlf file for my app and my library.

    Is there any news on that topic?

    If I follow your tip and add "extract-i18n" in the architects section of my lib. But I get the following message by now:

    Tried to extract from libs with 'projectType' library, which is not supported. The 'extract-i18n' builder can only extract from
    applications.

    So translating libraries isn't supported at all, although it is allegedly supported? https://v18.angular.dev/cli/extract-i18n

  19. sroucheray commented on Jan 27, 2025

    @sroucheray

    @alan-agius4 can you give us insights on technical reasons why we can't extract strings from a library? I understand that you think the translation responsibility should be on the application level but it seems a valid use case for a lot of us, library authors.
    Is it planned to support library at one point or not ? Would you accept external work to support it ?

  20. alan-agius4 commented on Jan 27, 2025

    @alan-agius4
    Collaborator

    For a library within a mono repo or a private NPM registry, this could be a valid use case. However, if the library is published on a public NPM registry, i18n should not be handled at the library level.

    This is generally a choice of a poor design. If the library requires translatable strings, they should be provided through configuration (e.g., Dependency Injection). Embedding i18n directly in the library forces the application to adopt i18n as well, which could make the library incompatible with non-i18n applications.

    As for why this hasn’t been added yet, there’s no specific "blocker." It's simply that other priorities are taking precedence, given the time and effort involved. We’d be happy to accept a PR, but it would require some design discussions and planning before implementation.

  21. meriturva commented on Jan 27, 2025

    @meriturva

    Thanks @alan-agius4 just to reply to your considerations:
    we have a vast enterprise application with more than 150 npm packages produced, we need a way to extract i18n on library-based to send them to translators (by Weblate).

    Currently, teams consuming our core libraries implement i18n and private localized string packages, which are then applied to XLIFF file using our schematics.

    However, we lack support for extracting i18n strings at the library level. At the moment, the only solution we've found is to generate a single massive file and then split it into smaller ones (library-based) using custom scripts.

    Thats our story!

  22. sroucheray commented on Jan 27, 2025

    @sroucheray

    @alan-agius4 I have no idea the time it would take to implement this, but I am willing to help. Would it be possible to have an outline of what you think is necessary for this feature to be accepted?

  23. added a commit that references this issue on Dec 17, 2025
  24. pb-aw-nl commented on May 11, 2026

    @pb-aw-nl

    Is it possible using extract-i18n to extract all translations from a library even if the components aren't referenced or used by the library itself. For instance the library contains dialogs or other ui building blocks without routing as this doesn't make any sence but the components contain i18n tags which you don't want to translate over and over again in all your clients (DRY). It seems impossible to get this done: only used components are scanned. Due to treeshaking?

  25. jonaskuske commented on Jul 30, 2026

    @jonaskuske

    Tried to extract from libs with 'projectType' library, which is not supported. The 'extract-i18n' builder can only extract from
    applications.

    So translating libraries isn't supported at all, although it is allegedly supported? https://v18.angular.dev/cli/extract-i18n

    This is very confusing. Not supporting libraries, unfortunate but oh well. But since the docs claim "Can be an application or a library." at https://angular.dev/cli/extract-i18n#arguments, it took me quite long to realize this is just not possible atm.

  26. india-e commented on Oct 16, 2026

    @india-e

    29. > Tried to extract from libs with 'projectType' library, which is not supported. The 'extract-i18n' builder can only extract from
    > applications.
    > So translating libraries isn't supported at all, although it is allegedly supported? https://v18.angular.dev/cli/extract-i18n

     This is very confusing. Not supporting libraries, unfortunate but oh well. But since the docs claim _"Can be an application or a library."_ at https://angular.dev/cli/extract-i18n#arguments, it took me quite long to realize this is just not possible atm.
    

    agree, the docs should be updated to make this clear.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions