or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

compilation.mdextraction.mdformatters.mdindex.mdverification.md
tile.json

extraction.mddocs/

Message Extraction

Core message extraction functionality for discovering and extracting translatable strings from source code using various methods including defineMessages, FormattedMessage components, and intl.formatMessage calls.

Capabilities

Extract Function

Extracts messages from source files and returns structured data.

/**
 * Extract messages from source files
 * @param files - Array of file paths to extract from
 * @param opts - Extraction options
 * @returns Promise resolving to formatted JSON string
 */
function extract(files: readonly string[], opts: ExtractOpts): Promise<string>;

interface ExtractOpts {
  /** Whether to throw an error if we had any issues with 1 of the source files */
  throws?: boolean;
  /** Message ID interpolation pattern */
  idInterpolationPattern?: string;
  /** Whether we read from stdin instead of a file */
  readFromStdin?: boolean;
  /** Either path to a formatter file or Formatter object */
  format?: string | Formatter<any>;
  /** Whether to hoist selectors & flatten sentences */
  flatten?: boolean;
  /** Extract source location metadata */
  extractSourceLocation?: boolean;
  /** Remove default message from output */
  removeDefaultMessage?: boolean;
  /** Additional component names to extract messages from */
  additionalComponentNames?: string[];
  /** Additional function names to extract messages from */
  additionalFunctionNames?: string[];
  /** Custom pragma for metadata extraction */
  pragma?: string;
  /** Preserve whitespace and newlines */
  preserveWhitespace?: boolean;
  /** Callback when message is extracted */
  onMsgExtracted?: (filePath: string, msgs: MessageDescriptor[]) => void;
  /** Callback when metadata is extracted */
  onMetaExtracted?: (filePath: string, meta: Record<string, string>) => void;
}

interface ExtractionResult<M = Record<string, string>> {
  /** List of extracted messages */
  messages: MessageDescriptor[];
  /** Metadata extracted w/ pragma */
  meta?: M;
}

Extract and Write Function

Extracts messages and writes them directly to a file.

/**
 * Extract messages and write to output file
 * @param files - Array of file paths to extract from
 * @param opts - CLI extraction options
 */
function extractAndWrite(files: readonly string[], opts: ExtractCLIOptions): Promise<void>;

interface ExtractCLIOptions extends Omit<ExtractOpts, 'overrideIdFn' | 'onMsgExtracted' | 'onMetaExtracted'> {
  /** Output file path */
  outFile?: string;
  /** Input file containing list of files to extract from */
  inFile?: string;
  /** Ignore file glob patterns */
  ignore?: string[];
}

Message Descriptor Types

interface MessageDescriptor {
  /** Message ID */
  id: string;
  /** Default message text */
  defaultMessage?: string;
  /** Description for translators */
  description?: string | object;
  /** Source file path */
  file?: string;
  /** Start position in source */
  start?: number;
  /** End position in source */
  end?: number;
}

interface ExtractedMessageDescriptor extends MessageDescriptor {
  /** Line number in source file */
  line?: number;
  /** Column number in source file */
  col?: number;
  /** Metadata extracted from pragma */
  meta?: Record<string, string>;
}

Usage Examples

Basic Extraction

import { extract } from "@formatjs/cli-lib";

// Extract from TypeScript/JSX files
const result = await extract(['src/**/*.{ts,tsx}'], {
  idInterpolationPattern: '[sha512:contenthash:base64:6]',
  extractSourceLocation: true
});

console.log(`Extracted ${result.messages.length} messages`);

Advanced Extraction with Custom Options

import { extractAndWrite } from "@formatjs/cli-lib";

// Extract with custom component and function names
await extractAndWrite(['src/**/*.{js,jsx}'], {
  outFile: 'messages/extracted.json',
  additionalComponentNames: ['MyFormattedMessage', 'T'],
  additionalFunctionNames: ['t', '$t'],
  pragma: 'intl-meta',
  flatten: true,
  preserveWhitespace: false,
  throws: true
});

Extraction with Formatter

import { extract } from "@formatjs/cli-lib";

// Use built-in formatter
const result = await extract(['src/components/*.tsx'], {
  format: 'smartling',
  idInterpolationPattern: '[contenthash:5]'
});

// Use custom formatter file
const customResult = await extract(['src/pages/*.tsx'], {
  format: './custom-formatter.js'
});

Extraction with Metadata

import { extract } from "@formatjs/cli-lib";

const result = await extract(['src/features/*.tsx'], {
  pragma: 'intl-meta',
  onMsgExtracted: (filePath, messages) => {
    console.log(`Extracted ${messages.length} messages from ${filePath}`);
  },
  onMetaExtracted: (filePath, meta) => {
    console.log(`Extracted metadata from ${filePath}:`, meta);
  }
});

CLI Options

When using the CLI directly:

# Basic extraction
formatjs extract 'src/**/*.{js,jsx,ts,tsx}' --out-file messages.json

# With custom ID pattern
formatjs extract 'src/**/*.tsx' --out-file messages.json --id-interpolation-pattern '[hash:base64:8]'

# With additional component names
formatjs extract 'src/**/*.jsx' --out-file messages.json --additional-component-names 'T,Trans'

# With source location extraction
formatjs extract 'src/**/*.tsx' --out-file messages.json --extract-source-location

# With pragma for metadata
formatjs extract 'src/**/*.jsx' --out-file messages.json --pragma 'intl-meta'

# With flattening for better translator experience
formatjs extract 'src/**/*.tsx' --out-file messages.json --flatten

# With ignore patterns
formatjs extract 'src/**/*.tsx' --out-file messages.json --ignore '**/test/**'

ID Interpolation Patterns

The idInterpolationPattern option supports various patterns for auto-generating message IDs:

  • [sha512:contenthash:base64:6] - SHA-512 hash of content, base64 encoded, 6 characters (default)
  • [sha1:contenthash:base64:8] - SHA-1 hash, 8 characters
  • [contenthash:5] - Generic hash, 5 characters
  • [hash:base64:10] - Generic hash, base64 encoded, 10 characters

Supported File Types

FormatJS CLI can extract messages from:

  • JavaScript/TypeScript: .js, .jsx, .ts, .tsx files
  • Vue.js: .vue files (requires @vue/compiler-core peer dependency)
  • Glimmer/Ember: .gts, .gjs files and .hbs templates (requires @glimmer/syntax peer dependency)

Error Handling

import { extract } from "@formatjs/cli-lib";

try {
  const result = await extract(['src/**/*.tsx'], {
    throws: true, // Throw on any processing errors
    onMsgExtracted: (filePath, messages) => {
      // Handle successful extraction
    }
  });
} catch (error) {
  console.error('Extraction failed:', error.message);
}