Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I localize my Angular 11 library?

I'm refactoring my Angular 11 application into libraries. My regular application is localized using @angular/localize as a dev dependency, so I have made use of the $localize directive in part of my code. I need to move this code with this directive into a library, but I can't figure out how to do this.

In my library's package.json file, I've added a peer-dependency on @angular/localize to match the devDependency in my application:

{
  "name": "example",
  "version": "0.0.1",
  "peerDependencies": {
    "@angular/common": "^11.0.0",
    "@angular/core": "^11.0.0",
    "@angular/localize": "~11.0.0"
  },
  "dependencies": {
    "tslib": "^2.0.0"
  }
}

However the compiler reports that it can't find $localize when I try to do ng build <library name>.

× Compiling TypeScript sources through NGC
ERROR: projects/example/src/lib/example.service.ts:52:23 - error TS2304: Cannot find name '$localize'.

52         description = $localize `example localized text`;
                         ~~~~~~~~~

How can I use the $localize directive in my library?

>ng version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 11.0.1
Node: 12.18.3
OS: win32 x64

Angular: 11.0.0
... animations, cdk, common, compiler, compiler-cli, core, forms
... localize, material, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1100.1
@angular-devkit/build-angular   0.1100.1
@angular-devkit/core            11.0.1
@angular-devkit/schematics      11.0.1
@angular/cli                    11.0.1
@schematics/angular             11.0.1
@schematics/update              0.1100.1
ng-packagr                      11.0.3
rxjs                            6.6.3
typescript                      4.0.5
like image 218
Roddy of the Frozen Peas Avatar asked Nov 28 '20 18:11

Roddy of the Frozen Peas


People also ask

What is angular localize?

The @angular/localize package exposes the $localize function in the global namespace, which can be used to tag i18n messages in your code that needs to be translated.

How would you implement localization in angular using i18n tools?

Open the angular. json file and add the following configuration. Here we have added the configuration for the Spanish language. We have provided the path and format for the i18n file and set the locale to "es." When we execute the application, the app content will be served from the i18n file path provided.

What is localization and internationalization in angular?

Angular Internationalizationlink Internationalization, sometimes referenced as i18n, is the process of designing and preparing your project for use in different locales around the world. Localization is the process of building versions of your project for different locales.

How do I add @angular/localize/init to my project?

Please run `ng add @angular/localize` from the Angular CLI. (For non-CLI projects, add `import '@angular/localize/init';` to your polyfills.ts file) This schematic automatically adds the @angular/localize/init import for you if your app uses Angular's i18n APIs.

What is localization in Angular 7?

Localization is the process for translating the app to a particular language. We need to apply internationalization to the application and after that we can localize it. Localization allows us to serve our application in different languages. The first step is to create an Angular 7 app.

How do I localize a number in angular?

How do I localize numbers in my Angular app? The simplest way to localize numbers is to use Angular’s built-in formatting pipes in our component templates. These pipes will use the active locale for formatting by default.

What is the default locale in angular?

Each locale is represented by a Unicode locale identifier, which specifies the language code and the locale extension. Angular's default locale is 'en-US', which is the language code 'en' (English) as spoken in the region ‘United States of America’.


3 Answers

First: install @angular/localize package.

npm i @angular/localize -D

Second: Find entryFile in your ng-package.json file, in my case public-api.ts

{
  "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
  "dest": "../../dist/ngx-my-lib",
  "lib": {
    "entryFile": "src/public-api.ts" // <=== this line
  }
}

Third: add import '@angular/localize/init'; to your entryFile, in my case public-api.ts

import '@angular/localize/init'; // <=== this line

export * from './lib/ngx-my-lib.service';
export * from './lib/ngx-my-lib.component';
export * from './lib/ngx-my-lib.module';
like image 165
Mohammad Dayyan Avatar answered Sep 30 '22 09:09

Mohammad Dayyan


Solved it by:

  1. Creating a typings.d.ts file next to the library's src folder.
  2. Put inside: declare function $localize(messageParts: TemplateStringsArray, ...expressions: readonly any[]): string;

Error disappear and compiler finds the translation parts with no problem.

like image 36
Ion Prodan Avatar answered Sep 30 '22 10:09

Ion Prodan


You have to put import '@angular/localize/init'; inside src/polyfills.ts of the main project. Also have to configure the angular.json for your main project (not the library) to be able to use the localization.

You have to configure the angular.json like so depending on your locales:

"projects": {
    "the-name-of-your-project": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "i18n": {
        "sourceLocale": "en-US",
        "locales": {
          "fr": "fr-messages.xlf"
        }
      },
      ...
      "architect": {
        ...
        "configurations": {
            "fr": { "localize": ["fr"] },
            ...
         }
      },
      "serve": {
          ...
          "configurations": {
            "fr": {
                "browserTarget": "angular-material-timepicker:build:fr"
              }
           }
           ...
       }

}

You can check out the different sections that I had in my project and with which everything was working by clicking these links: 1, 2, 3 or view the whole file.

The problem with this approach is that if you have it as a dependency, all the users of your library will have to install it and put and configure it manually as well, even if they don't need it.

I'm managing this angular material timepicker module and I removed this dependency in favour of using this - Mark element attributes for translations. Notice the i18n-title attribute:

<img [src]="logo" i18n-title title="Angular logo" />

So now all users have to do is just use the i18n-<name_of_input> and everything works fine and you don't need to bother dealing with localize.

So if your library component/directive has an input lets say title that you want to be translated you can just put i18n-title="some title|An introduction title for this sample@@introductionComponent" and everything works great.

like image 38
user1 Avatar answered Sep 30 '22 08:09

user1