Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@jsverse/transloco-keys-manager

jsverse99.7kMIT6.1.0TypeScript support: included

Extract translatable keys from projects that uses Transloco

angular, angular 2, i18n, extract, transloco, translate, keys, tool, cli, webpack

readme

[!IMPORTANT]
The Transloco packages are now published under the @jsverse scope, update your dependencies to get the latest features 🚀

🦄 The Key to a Better Translation Experience

Build Status NPM Version

Translation is a tiresome and repetitive task. Each time we add new text, we need to create a new entry in the translation file, find the correct placement for it, etc. Moreover, when we delete existing keys, we need to remember to remove them from each translation file.

To make the process less burdensome, we've created two tools for the Transloco library, which will do the monotonous work for you.

🍻Features

  • ✅  Extract Translate Keys
  • ✅  Scopes Support
  • ✅  Webpack Plugin
  • ✅  Find Missing and Extra Keys

📖 Table of Contents

🌩 Installation

Schematics

Assuming you've already added Transloco to your project, run the following schematics command:

ng g @jsverse/transloco:keys-manager

At this point, you'll have to choose whether you want to use the CLI, Webpack Plugin, or both. The project will be updated according to your choice.

Note: if you're going to use the Webpack plugin, and you've already defined other Webpack plugins in your project, you should manually add the Keys Manager plugin to the list, rather than using the schematics command.

Manual

Install the Transloco keys manager package via yarn or npm by running: `shell script npm i -D @jsverse/transloco-keys-manager yarn add -D @jsverse/transloco-keys-manager


Add the following scripts to your `package.json` file:
```json
{
  "i18n:extract": "transloco-keys-manager extract",
  "i18n:find": "transloco-keys-manager find"
}

#

The following functionality is available once the installation is complete:

🔑 Keys Extractor

This tool extracts translatable keys from templates and typescript files. Transloco Keys Manager provides two ways of using it:

CLI Usage

If you chose the CLI option, you should see the following script in your project's package.json file:

{
  "i18n:extract": "transloco-keys-manager extract"
}

Run npm run i18n:extract, and it'll extract translatable keys from your project.

Webpack Plugin

The TranslocoExtractKeysWebpackPlugin provides you with the ability to extract the keys during development, while you're working on the project.

The angular-cli doesn't support adding a custom Webpack config out of the box.

In case you already have support for a custom Webpack config just add the TranslocoExtractKeysWebpackPlugin in your plugin list.

In case you need to add the support, you can use the keys manager schematics command, and it will do the work for you. (choose the Webpack Plugin option)

You should see a new file named webpack-dev.config.js configured with TranslocoExtractKeysWebpackPlugin:

// webpack-dev.config.js
import { TranslocoExtractKeysWebpackPlugin } from '@jsverse/transloco-keys-manager';

export default {
  plugins: [
    new TranslocoExtractKeysWebpackPlugin(config?),
  ]
};

Also, you should see an updated definition of the npm start command:

{
  "start": "ng serve --extra-webpack-config webpack-dev.config.js"
}

Now run npm start and it'll generate new keys whenever a save is made to the project.

Scopes Support

The extractor supports scopes out of the box. When you define a new scope in the providers array:

import { TRANSLOCO_SCOPE, provideTranslocoScope } from '@jsverse/transloco';

@Component({
  templateUrl: './admin-page.component.html',
  providers: [
      { provide: TRANSLOCO_SCOPE, useValue: 'admin' },
      provideTranslocoScope('todo'),
      provideTranslocoScope(['another', {scope: 'reallyLong', alias: 'rl'}]),
  ]
})
export class AdminPageComponent {}
<ng-container *transloco="let t">{{ t('admin.title') }}</ng-container>

It'll extract the scope (admin in our case) keys into the relevant folder:

📦 assets
 ┗ 📂 i18n
 ┃ ┣ 📂 admin
 ┃ ┃ ┣ 📜 en.json
 ┃ ┃ ┗ 📜 es.json
 ┃ ┣ 📜 en.json
 ┃ ┗ 📜 es.json

Inline Loaders

Let's say that we're using the following inline loader:

export const loader = ['en', 'es'].reduce((acc, lang) => {
  acc[lang] = () => import(`../i18n/${lang}.json`);
  return acc;
}, {});

@NgModule({
  imports: [TranslocoModule],
  providers: [
    {
      provide: TRANSLOCO_SCOPE,
      useValue: {
        scope: 'scopeName',
        loader
      }
    }
  ],
  declarations: [YourComponent],
  exports: [YourComponent]
})
export class FeatureModule {}

We can add it to the scopePathMap key in the transloco.config.js file:

module.exports = {
  langs: ['en', 'es'],
  scopePathMap: {
    scopeName: 'src/app/feature/i18n'
  }
};

Now, it'll create the files in the provided folder.

Dynamic Keys

There are times when we need to extract keys with values that may change during runtime. One example can be when you need to use a dynamic expression:

import { TranslocoService } from '@jsverse`/transloco';

class MyComponent {
  someMethod() {
    const value = translocoService.translate(`key.${type}.postfix`);
  }
}

To support such cases, you can add a special comment to your code, which tells the CLI to extract it. It can be added to Typescript files:

import { TranslocoService } from '@jsverse/transloco';

class MyComponent {
  /**
   * t(key.typeOne.postfix, key.typeTwo.postfix)
   * t(this.will.be.extracted)
   */
  someMethod() {
    const value = translocoService.translate(`key.${type}.postfix`);
  }
}

Or to templates:

<!-- t(I.am.going.to.extract.it, this.is.cool) -->
<ng-container *transloco="let t">...</ng-container>

When using comments in the templates they will also inherit the prefix input value (if exists), and will be prefixed with it:

<!-- t(this.is.cool) -->
<ng-container *transloco="let m; prefix: 'messages'">
  ...
  <!-- t(success, error) -->
  <ng-container *transloco="let g; prefix: 'general'">
    ...
    <!-- t(ok, cancel) -->
  </ng-container>
</ng-container>

The extracted keys for the code above will be:

{
  "this.is.cool": "",
  "messages.success": "",
  "messages.error": "",
  "general.ok": "",
  "general.cancel": ""
}

Notes:

  1. When using a Typescript file, you must have @jsverse/transloco present somewhere in the file, if it's an import or simply adding a comment // @jsverse/transloco.
  2. When using comments in your HTML files, they must contain only the markers without additional text. Here's an example for invalid comment: <!-- For dropdown t(dynamic.1, dynamic.2) -->

Marker function

If you want to extract some standalone strings that are not part of any translation call (via the template or service) you can wrap them with the marker function to tell the keys manager to extract them:

import { marker } from '@jsverse/transloco-keys-manager';

class MyClass {
  static titles = {
    username: marker('auth.username'), // ==> 'auth.username'
    password: marker('auth.password') // ==> 'auth.password'
  };
...
}

The marker function will return the string which was passed to it. You can alias the marker function if needed:

import { marker as _ } from '@jsverse/transloco-keys-manager';

class MyClass {
  static titles = {
    username: _('auth.username'),
    password: _('auth.password')
  };
...
}

Extra Support

  • Supports for the prefix input:
<ng-container *transloco="let t; prefix: 'dashboard'">
  <h1>{{ t('title') }}</h1>

  <p>{{ t('desc') }}</p>
</ng-container>

The extracted keys for the code above will be:

{
  "dashboard.title": "",
  "dashboard.desc": ""
}
  • Supports static ternary operators:
<!-- Supported by the transloco pipe and structural directive -->
<comp [placeholder]="condition ? 'keyOne' : 'keyTwo' | transloco"></comp>
<h1>{{ condition ? 'keyOne' : 'keyTwo' | transloco }}</h1>

<comp *transloco="let t; prefix: 'ternary'">
  <h1>{{ t(condition ? 'keyOne' : 'keyTwo') }}</h1>
</comp>
  • Supports params:
<comp *transloco="let t;">
  <h1>{{ t('key', {value: '123', another: property}) }}</h1>
  <p>{{ 'description' | transloco:{'param': 123} }}</p>
  <footer transloco="footer" [translocoParams]="{param: 123}"></footer>
</comp>
import {translate} from '@jsverse/transloco';

translate('key', {param: 123});

class MyComponent {
  someMethod() {
    const value = translocoService.translate(`key`, {param: 123});
    const value$ = translocoService.selectTranslate(`key`, {param: 123});
    // Only literal params are supported, the following won't be extracted:   
    translocoService.translate(`key`, this.myParams);
  }
}

🕵 Keys Detective

This tool detects two things: First, it detects any key that exists in one of your translation files but is missing in any of the others. Secondly, it detects any key that exists in the translation files but is missing from any of the templates or typescript files. After installing the library, you should see the following script in your project's package.json file:

{
  "i18n:find": "transloco-keys-manager find"
}

Run npm run i18n:find, and you'll get a lovely list that summarizes the keys found.

🕹 Options

  • config: The root search directory for the transloco config file: (default is process.cwd())
transloco-keys-manager extract --config src/my/path
transloco-keys-manager extract -c src/my/path
  • project: The targeted project (default is defaultProject). The sourceRoot of this project will be extracted from the angular.json file and will prefix *the default** input, output, and translationPath properties, So when overriding these options make sure you provide the full path. In addition, the transloco config file will be searched in the project's sourceRoot (unless the config option is passed):
transloco-keys-manager extract --project first-app

Note: If no angular.json file is present, sourceRoot will be src.

  • translationsPath: The path for the root directory of the translation files (default is ${sourceRoot}/assets/i18n)
transloco-keys-manager find --translations-path src/assets/my/path
transloco-keys-manager find -p src/assets/my/path
  • input: The source directory for all files using the translation keys: (default is [${sourceRoot}/app'])
transloco-keys-manager extract --input src/my/path
transloco-keys-manager extract --input src/my/path,project/another/path
transloco-keys-manager extract -i src/my/path

Note: If a project is provided the default input value will be determined by the projectType, when given a library the default input value will be ['${sourceRoot}/lib'].

  • output: The target directory for all generated translation files: (default is ${sourceRoot}/assets/i18n)
transloco-keys-manager extract --output my/path
transloco-keys-manager extract -o my/path
  • fileFormat: The translation file format 'json' | 'pot': (default is json)
transloco-keys-manager extract --file-format pot
transloco-keys-manager extract -f pot
  • langs: The languages files to generate: (default is [en])
transloco-keys-manager extract --langs en es it
transloco-keys-manager extract -l en es it
  • marker: The marker sign for dynamic values: (default is t)
transloco-keys-manager extract --marker _
transloco-keys-manager extract -m  _
  • sort: Whether to sort the keys using JS sort() method: (default is false)
transloco-keys-manager extract --sort
  • unflat: Whether to unflat instead of flat: (default is flat)
transloco-keys-manager extract --unflat
transloco-keys-manager extract -u

If you are using unflat files keep in mind that “parent” keys won't be usable for a separate translation value, i.e. if you have two keys first and first.second you cannot assign a value to first as the translation file will look like { "first": { "second": "…" } }.

During key extraction you will get a warning with a list of concerned keys you have to check for.

  • defaultValue: The default value of a generated key: (default is Missing value for {{key}})
transloco-keys-manager extract --default-value missingValue
transloco-keys-manager extract -d "{{key}} translation is missing"

There are several placeholders that are replaced during extraction:

  1. {{key}} - complete key including the scope.
  2. {{keyWithoutScope}} - key value without the scope.
  3. {{scope}} - the key's scope.
  4. {{params}} - the params used for this key.
  • replace: Replace the contents of a translation file (if it exists) with the generated one (default value is false, in which case files are merged)
transloco-keys-manager extract --replace
transloco-keys-manager extract -r
  • removeExtraKeys: Remove extra keys from existing translation files (defaults to false)
transloco-keys-manager extract --remove-extra-keys
transloco-keys-manager extract -R
  • addMissingKeys: Add missing keys that were found by the detective (default is false)
transloco-keys-manager find --add-missing-keys
transloco-keys-manager find -a
  • emitErrorOnExtraKeys: Emit an error and exit the process if extra keys were found (default is false)
    Extra keys are keys that exist in your translations but are no usages of them in the code.
transloco-keys-manager find --emit-error-on-extra-keys
transloco-keys-manager find -e
  • help:
transloco-keys-manager --help
transloco-keys-manager -h

Transloco Config File

If you installed transloco via the schematics, a transloco.config.ts should have been created. Otherwise, you can just create a transloco.config.ts in the project's root folder and add the configuration in it:

import {TranslocoGlobalConfig} from "@jsverse/transloco-utils";

const config: TranslocoGlobalConfig = {
  rootTranslationsPath?: string;
  langs?: string[];
  keysManager: {
    input?: string | string[];
    output?: string;
    fileFormat?: 'json' | 'pot';
    marker?: string;
    addMissingKeys?: boolean;
    emitErrorOnExtraKeys?: boolean;
    replace?: boolean;
    defaultValue?: string | undefined;
    unflat?: boolean;
  }
};

export default config;

🐞 Debugging

You can extend the keys manager default logs by setting the DEBUG environment variable:

{
  "i18n:extract": "DEBUG=tkm:config,tkm:paths transloco-keys-manager extract",
  "i18n:find": "DEBUG=* transloco-keys-manager find"
}

Supported namespaces: tkm:*|config|paths|scopes|extraction, setting tkm:* will print all the debugger logs.

Contributors ✨

Thank goes to all these wonderful people who contributed ❤️

changelog

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

6.1.0 (2024-12-19)

Features

6.0.0 (2024-10-30)

⚠ BREAKING CHANGES

  • 🧨 The keys manager debug spaces are now perfixed with tkm

Features

  • 💡 prefix debug namespaces with tkm (c039711)

5.1.0 (2024-08-06)

Features

  • 🎸 support params in pipe and directive (020e6bc), closes #153
  • 🎸 support pipe params extraction (d867d5c)
  • 🎸 support structural directive params extraction (5e11689), closes #153
  • 🎸 support ts params extraction (0ccbe95), closes #153

5.0.0 (2024-07-26)

⚠ BREAKING CHANGES

  • 🧨 The source root won't be automatically prefixed to the input, outputand translationsPath anymore. for more inforamtion see the BREAKING_CHANGES.md file.

Features

  • 🎸 Support scanning arbitrary folders (4979e83), closes #160

4.2.4 (2024-07-18)

Bug Fixes

  • 🐛 support inject assignment to a variable (a326b78), closes #141

4.2.3 (2024-07-18)

Bug Fixes

  • 🐛 find throws Translations path missing (12fbadd), closes #163

4.2.2 (2024-06-14)

Bug Fixes

4.2.1 (2024-06-13)

Bug Fixes

  • 🐛 keys detective should respect the unflat option (21e02ed), closes #195

4.2.0 (2024-04-29)

Features

  • 🎸 Add support for prefix attribute and providers array (df064eb)
  • 🎸 add support of provideTranslocoScope (#190) (5f59487)

4.1.1 (2024-04-19)

Bug Fixes

  • 🐛 TypeScript prefix cast operator ast issue (1cf3ab8), closes #192

4.1.0 (2024-04-01)

Features

Bug Fixes

4.0.1 (2024-03-26)

Bug Fixes

4.0.0 (2024-03-23)

⚠ BREAKING CHANGES

  • 🧨 Imports path changes to @jsverse/transloco-keys-manager
  • 🧨 The lib is now ESM

Features

  • 🎸 Add support for self closing tag and control flow (#180) (0e3ab54)

3.8.0 (2024-03-15)

Features

  • 🎸 Add support for angular 14 inject() (#142) (0d69c07)

Bug Fixes

  • only seach ts files for scopes (#164) (d3e583f)
  • writeFileSync expects encoding to be in lowercase (#157) (9ba5f61)

3.8.0 (2023-08-13)

Features

  • 🎸 Add support for angular 14 inject() (#142) (0d69c07)

Bug Fixes

  • only search ts files for scopes (#164) (d3e583f)
  • writeFileSync expects encoding to be in lowercase (#157) (9ba5f61)

3.7.0 (2023-03-25)

Features

  • 🎸 add option to delete missing keys (e19baa9)

3.6.2 (2023-03-05)

Bug Fixes

3.6.1 (2023-03-04)

Bug Fixes

  • added a glob ignore to the resolveProjectBasePath (#150) (111bc3f)

3.6.0 (2023-03-04)

Features

  • 🎸 support workspaces without root configs (2a8bbe8), closes #149

3.5.0 (2022-12-16)

Features

  • 🎸 use jsonc-parser to parse configs (#147) (66a5cde)

3.4.2 (2022-08-19)

Bug Fixes

  • 🐛 scope mapping throws an error (c696694), closes #136

3.4.1 (2022-04-08)

Bug Fixes

  • 🐛 support scopes with array as value (425f34c), closes #128

3.4.0 (2022-04-08)

Features

  • support pot format for the translation files (#124) (658c4b0), closes #45

3.3.6 (2022-04-05)

3.3.5 (2022-03-31)

3.3.4 (2022-03-31)

3.3.3 (2022-01-23)

Bug Fixes

3.3.2 (2022-01-22)

Bug Fixes

  • 🐛 extract keys from template attrs (e27d750), closes #119

3.3.1 (2022-01-21)

Bug Fixes

  • 🐛 take first project from config if no default (0c8f1bb)

3.3.0 (2022-01-21)

Features

  • 🎸 support project level config (0cb4bbd), closes #116

3.2.1 (2022-01-10)

Bug Fixes

3.2.0 (2021-11-17)

Features

3.1.1 (2021-11-04)

Bug Fixes

  • 🐛 import for @jsverse/transloco-utils (#113) (e8ee33b)

3.1.0 (2021-10-31)

Features

  • 🎸 support workspace.json configs (953deaa), closes #72

3.0.4 (2021-10-28)

Bug Fixes

3.0.3 (2021-10-28)

3.0.2 (2021-10-07)

Bug Fixes

  • 🐛 Keys Extractor does not extract key arrays (#112) (852ccee)

3.0.1 (2021-09-28)

Bug Fixes

3.0.0 (2021-09-27)

Features

  • 🎸 run prettier on generated files (6386b09), closes #79
  • 🎸 support inline templates (a0b9eaa), closes #83

2.7.5 (2021-09-13)

Bug Fixes

  • 🐛 false positive of prefix+marker(keys) inside comments (#104) (eb71f58)

2.7.4 (2021-07-15)

Bug Fixes

2.7.3 (2021-07-13)

Bug Fixes

  • 🐛 use webpack 5's modified file list when available (#99) (6466972), closes #98

2.7.2 (2021-04-17)

2.7.1 (2020-12-12)

Bug Fixes

2.7.0 (2020-10-31)

Features

  • 🎸 extend the default value replaceable options (4f6cdbc)

2.6.0 (2020-09-20)

Features

  • 🎸 support library extraction (3d6c287), closes #54

2.5.0 (2020-09-20)

Features

  • 🎸 exclude comments as extra keys in detective (6bef047), closes #56

2.4.2 (2020-09-19)

Bug Fixes

  • 🐛 webpack wrong extraction when unflat with several langs (33cb1cb), closes #46

2.4.1 (2020-09-19)

Bug Fixes

2.4.0 (2020-09-19)

Features

  • 🎸 support ternary operator in structural directive (#47) (440d8d3)

2.3.2 (2020-09-19)

2.3.1 (2020-09-12)

Bug Fixes

  • 🐛 scoped comments were added on a global level (f2b00be), closes #50

Tests

2.3.0 (2020-09-12)

Features

2.2.1 (2020-06-22)

Bug Fixes

  • 🐛 add polyfill to support older node versions (57a3e8d)

2.2.0 (2020-06-21)

Features

  • 🎸 support multiple input paths (f6f21ab), closes #40

2.1.0 (2020-06-10)

Features

2.0.7 (2020-05-16)

Bug Fixes

  • 🐛 scopes map taken from the wrong config (1a2c7e2), closes #37

2.0.6 (2020-04-29)

Bug Fixes

  • 🐛 wrong pipe extraction (7d1d848), closes #32

2.0.5 (2020-04-28)

2.0.4 (2020-04-28)

Bug Fixes

  • 🐛 handle empty keys (71655e4), closes #30
  • 🐛 support empty string as default value (0f80435), closes #31

2.0.3 (2020-03-14)

2.0.2 (2020-02-03)

Bug Fixes

  • 🐛 extraction remove spaces from keys (6cd78ce), closes #26

2.0.1 (2020-02-02)

Bug Fixes

  • 🐛 exit the process when missing keys (4029ad2)

2.0.0 (2020-02-02)

Bug Fixes

  • 🐛 sort on all levels if using unflat (#22) (bab0a57)
  • 🐛 validate directory paths (d936b01), closes #21

Features

  • 🎸 add support for read in comments (9b6093a)

refactor

  • 💡 change base path default value and behavior (3f7729f)

Tests

BREAKING CHANGES

  • comments inside a container with read will be prefixed with the read's value
  • changed config.

1.3.2 (2020-01-13)

Bug Fixes

  • 🐛 fix paths and angular.json file read (b3f41c3)

1.3.1 (2020-01-13)

Bug Fixes

  • 🐛 cli options invalid alias (c43a439), closes #19
  • 🐛 regex should look for full word template key only (#18) (9d8cb86)

1.3.0 (2020-01-13)

Bug Fixes

  • 🐛 unflatten with number as last key (#16) (cb2cf07)

Features

  • 🎸 add config & project options (000aff5), closes #17

1.2.6 (2019-12-17)

Bug Fixes

  • 🐛 add fs-extra as a dependency (7b58b6d), closes #13
  • 🐛 keys detective flatten files before comparing (f87b128)

1.2.4 (2019-12-03)

Bug Fixes

  • 🐛 keys detective should find global keys (2e38f8c), closes #12
  • 🐛 should ignore unrelated methods (b4ae85a)

1.2.2 (2019-11-25)

Bug Fixes

1.2.1 (2019-11-24)

Bug Fixes

  • 🐛 fix PC directory path conflict (#9) (3e01c08)
  • 🐛 include only marking comments in the template (8883135), closes #10

1.2.0 (2019-11-19)

Bug Fixes

  • 🐛 remove legacy code which changed extracted keys (ee46e00), closes #7
  • 🐛 respect the langs in webpack plugin (10891ee), closes #5

Features

  • 🎸 support key injection in custom default value (581d933), closes #8

1.1.0 (2019-11-12)

Features

  • 🎸 support inline loaders and add nested option (080a318)

1.0.1 (2019-11-06)

1.1.0 (2019-11-06)

Bug Fixes

  • 🐛 comments extractions and pipe (3f8414b)
  • 🐛 pipe and sort keys when creating file (d411550)
  • 🐛 should not override the existing keys (268644d), closes #1

1.0.0 (2019-10-25)

Bug Fixes

  • 🐛 fix issues found in tests (ebe5711)
  • 🐛 fix scope mapping (84e0e20)
  • 🐛 fix scope mapping (1d7e94e)
  • 🐛 fix scope mapping (3cd9921)

Features

  • 🎸 support marker (06d47bc)
  • 🎸 update script to work with transloco v2 (1db6527)

Tests

  • 💍 Add testing playground (555191a)

1.0.0 (2019-11-05)

Bug Fixes

  • 🐛 fix issues found in tests (ebe5711)

Features

  • 🎸 update script to work with transloco v2 (1db6527)

Tests

  • 💍 Add testing playground (555191a)