Command-line utilities for message extraction, source file translation, and legacy code migration integrated with the Angular CLI and build processes.
Extracts translatable messages from source files and outputs them in various translation file formats.
Binary: localize-extract
Location: ./node_modules/.bin/localize-extract
Command Line Usage:
# Basic extraction
localize-extract --source="./dist/**/*.js" --format=xlf --outputPath=./locale
# With custom options
localize-extract \
--source="./dist/**/*.js" \
--format=json \
--outputPath=./i18n \
--locale=en \
--rootPath=./distOptions:
| Option | Alias | Description | Default |
|---|---|---|---|
--locale | -l | Locale of source being processed | en |
--root | -r | Root path for other relative paths | . |
--source | -s | Glob pattern for files to search | Required |
--format | -f | Output format (xlf, xlf2, xmb, json, arb) | Required |
--outputPath | -o | Output directory path | Required |
--duplicateMessageHandling | -d | How to handle duplicates (error, warning, ignore) | warning |
Translates source files using provided translation files, replacing $localize calls with translated strings.
Binary: localize-translate
Location: ./node_modules/.bin/localize-translate
Command Line Usage:
# Basic translation
localize-translate --source="./dist/**/*.js" --target=./dist-es --translations="./locale/messages.es.xlf"
# Multiple locales
localize-translate \
--source="./dist/**/*.js" \
--target=./dist-i18n \
--translations="./locale/messages.*.xlf" \
--outputPath="./dist-i18n/{locale}"Options:
| Option | Description | Default |
|---|---|---|
--source | Glob pattern for source files to translate | Required |
--target | Output directory for translated files | Required |
--translations | Glob pattern for translation files | Required |
--outputPath | Path template for locale-specific output | {target}/{locale} |
--missingTranslation | How to handle missing translations (error, warning, ignore) | warning |
Migrates legacy Angular i18n usage to $localize format, updating source files to use the new API.
Binary: localize-migrate
Location: ./node_modules/.bin/localize-migrate
Command Line Usage:
# Basic migration
localize-migrate --files="./src/**/*.ts"
# With options
localize-migrate \
--files="./src/**/*.ts" \
--mapFile=./migration-map.jsonOptions:
| Option | Description | Default |
|---|---|---|
--files | Glob pattern for files to migrate | Required |
--mapFile | Path to mapping file for legacy IDs | Optional |
Programmatically extracts translatable messages from source files.
/**
* Extracts translatable messages from source files.
* Analyzes code to find $localize tagged template literals.
*/
class MessageExtractor {
/**
* Extract messages from source file paths.
*
* @param rootPaths - Array of root paths to search
* @param options - Extraction configuration options
* @returns Array of parsed messages found in source files
*/
extractMessages(
rootPaths: string[],
options: ExtractorOptions
): ParsedMessage[];
}
interface ExtractorOptions {
/** Base path for resolving relative paths */
basePath?: string;
/** How to handle duplicate message IDs */
duplicateMessageHandling?: DiagnosticHandlingStrategy;
/** Source locale identifier */
sourceLocale?: string;
/** File patterns to include/exclude */
filePattern?: string;
}Usage Example:
import { MessageExtractor } from "@angular/localize/tools";
const extractor = new MessageExtractor();
const messages = extractor.extractMessages(
['./dist/**/*.js'],
{
basePath: process.cwd(),
sourceLocale: 'en',
duplicateMessageHandling: 'warning'
}
);
console.log(`Found ${messages.length} translatable messages`);
messages.forEach(msg => {
console.log(`${msg.id}: ${msg.text}`);
});High-level function for extracting translations with configuration.
/**
* Extract translations from source files with comprehensive configuration.
* Handles file discovery, message extraction, and output generation.
*
* @param config - Complete extraction configuration
*/
function extractTranslations(config: ExtractorConfig): void;
interface ExtractorConfig {
/** Source file patterns to extract from */
sourceFilePatterns: string[];
/** Output format for translation files */
format: 'xlf' | 'xlf2' | 'xmb' | 'json' | 'arb';
/** Output file path */
outputPath: string;
/** Source locale */
locale: string;
/** Base path for file resolution */
basePath?: string;
/** Duplicate handling strategy */
duplicateMessageHandling?: DiagnosticHandlingStrategy;
/** Format-specific options */
formatOptions?: FormatOptions;
}Usage Example:
import { extractTranslations } from "@angular/localize/tools";
extractTranslations({
sourceFilePatterns: ['./dist/**/*.js'],
format: 'xlf2',
outputPath: './locale/messages.xlf',
locale: 'en',
basePath: process.cwd(),
duplicateMessageHandling: 'error',
formatOptions: {
includeContext: true
}
});High-level function for translating source files.
/**
* Translate source files using translation files.
* Replaces $localize calls with translated strings.
*
* @param config - Translation configuration
*/
function translateFiles(config: TranslateConfig): void;
interface TranslateConfig {
/** Source file patterns to translate */
sourceFilePatterns: string[];
/** Translation file patterns */
translationFilePatterns: string[];
/** Output directory for translated files */
outputPath: string;
/** How to handle missing translations */
missingTranslation?: DiagnosticHandlingStrategy;
/** Base path for file resolution */
basePath?: string;
/** Whether to include source maps */
sourceMap?: boolean;
}Usage Example:
import { translateFiles } from "@angular/localize/tools";
translateFiles({
sourceFilePatterns: ['./dist/**/*.js'],
translationFilePatterns: ['./locale/messages.*.xlf'],
outputPath: './dist-i18n',
missingTranslation: 'warning',
basePath: process.cwd(),
sourceMap: true
});Utility for validating unique message IDs across extracted messages.
/**
* Check for duplicate message IDs and handle according to strategy.
* Ensures message ID uniqueness across translation units.
*
* @param messages - Array of parsed messages to check
* @param duplicateMessageHandling - How to handle duplicates
* @returns Array of unique messages (duplicates resolved)
*/
function checkDuplicateMessages(
messages: ParsedMessage[],
duplicateMessageHandling: DiagnosticHandlingStrategy
): ParsedMessage[];Usage Example:
import { checkDuplicateMessages } from "@angular/localize/tools";
const messages = [
{ id: '123', text: 'Hello', /* ... */ },
{ id: '123', text: 'Hello', /* ... */ }, // Duplicate
{ id: '456', text: 'World', /* ... */ }
];
const uniqueMessages = checkDuplicateMessages(messages, 'warning');
// Logs warning for duplicate, returns deduplicated arrayCreates replacement expressions for $localize calls during translation.
/**
* Build replacement expression for $localize tagged template literal.
* Used during source file translation to replace calls with translated strings.
*
* @param messageParts - Template string parts
* @param substitutions - Expression substitutions
* @returns Replacement expression string
*/
function buildLocalizeReplacement(
messageParts: TemplateStringsArray,
substitutions: Expression[]
): Expression;Checks if $localize is used as a global identifier in source files.
/**
* Check if $localize is used as global identifier.
* Determines if localize calls reference global vs imported function.
*
* @param node - AST node to check
* @returns True if node represents global $localize usage
*/
function isGlobalIdentifier(node: Node): boolean;Utilities for extracting parts from $localize calls and template literals.
/**
* Unwrap message parts from $localize function call.
* Extracts template literal parts from AST nodes.
*
* @param call - $localize call expression node
* @returns Array of message part strings
*/
function unwrapMessagePartsFromLocalizeCall(call: CallExpression): string[];
/**
* Unwrap message parts from template literal.
*
* @param literal - Template literal node
* @returns Array of message part strings
*/
function unwrapMessagePartsFromTemplateLiteral(literal: TemplateLiteral): string[];
/**
* Unwrap expressions from template literal.
*
* @param literal - Template literal node
* @returns Array of expression nodes
*/
function unwrapExpressionsFromTemplateLiteral(literal: TemplateLiteral): Expression[];
/**
* Unwrap substitution expressions from $localize call.
*
* @param call - $localize call expression node
* @returns Array of substitution expression nodes
*/
function unwrapSubstitutionsFromLocalizeCall(call: CallExpression): Expression[];Babel plugin for translating ES2015+ source files.
/**
* Create Babel plugin for translating ES2015+ $localize calls.
* Replaces tagged template literals with translated strings.
*
* @param translations - Translation mapping
* @param options - Plugin configuration options
* @returns Babel plugin function
*/
function makeEs2015TranslatePlugin(
translations: Record<string, ParsedTranslation>,
options?: TranslatePluginOptions
): BabelPlugin;Babel plugin for translating ES5 source files.
/**
* Create Babel plugin for translating ES5 $localize calls.
* Handles ES5-specific syntax and function call patterns.
*
* @param translations - Translation mapping
* @param options - Plugin configuration options
* @returns Babel plugin function
*/
function makeEs5TranslatePlugin(
translations: Record<string, ParsedTranslation>,
options?: TranslatePluginOptions
): BabelPlugin;Babel plugin for replacing locale identifiers in source files.
/**
* Create Babel plugin for replacing locale expressions.
* Replaces $localize.locale and similar expressions with locale string.
*
* @param locale - Target locale string
* @returns Babel plugin function
*/
function makeLocalePlugin(locale: string): BabelPlugin;Usage Example:
import { makeEs2015TranslatePlugin, makeLocalePlugin } from "@angular/localize/tools";
import { transformSync } from "@babel/core";
// Create translation plugin
const translatePlugin = makeEs2015TranslatePlugin(translations, {
missingTranslation: 'warning'
});
// Create locale plugin
const localePlugin = makeLocalePlugin('es');
// Transform source code
const result = transformSync(sourceCode, {
plugins: [translatePlugin, localePlugin]
});
console.log(result.code); // Translated source code/**
* Strategies for handling diagnostic messages (errors, warnings).
*/
enum DiagnosticHandlingStrategy {
Error = 'error',
Warning = 'warning',
Ignore = 'ignore'
}/**
* Handles diagnostic messages during extraction and translation.
* Manages error reporting and warning collection.
*/
class Diagnostics {
/** Add error diagnostic */
error(message: string): void;
/** Add warning diagnostic */
warn(message: string): void;
/** Get all collected messages */
messages: DiagnosticMessage[];
/** Check if any errors were reported */
hasErrors: boolean;
}
interface DiagnosticMessage {
type: 'error' | 'warning' | 'info';
message: string;
file?: string;
line?: number;
column?: number;
}The package includes Angular CLI integration via the ng add schematic:
# Install and configure @angular/localize
ng add @angular/localize
# This automatically:
# - Adds package dependency
# - Imports polyfill in polyfills.ts
# - Updates angular.json for i18n build configurationIntegration with Angular CLI build process:
// angular.json
{
"projects": {
"my-app": {
"i18n": {
"sourceLocale": "en-US",
"locales": {
"es": "src/locale/messages.es.xlf",
"fr": "src/locale/messages.fr.xlf"
}
},
"architect": {
"build": {
"configurations": {
"es": {
"aot": true,
"outputPath": "dist/es/",
"i18nFile": "src/locale/messages.es.xlf",
"i18nFormat": "xlf",
"i18nLocale": "es"
}
}
}
}
}
}
}# 1. Build for extraction
ng build --prod
# 2. Extract messages
ng extract-i18n
# OR manually:
localize-extract --source="./dist/**/*.js" --format=xlf --outputPath=./src/locale
# 3. Translate files (external process)
# 4. Build localized versions
ng build --configuration=es
ng build --configuration=fr