General Translation (gt)

repository·main·Indexed 21 days ago

https://github.com/generaltranslation/gt

A suite of i18n tools for React, Next.js, and React Native that simplifies internationalization by allowing developers to wrap components in a <T> tag instead of managing separate translation dictionaries. The ecosystem includes libraries such as gt-react, gt-next, and gt-react-native, as well as the @generaltranslation/compiler plugin for build-time message extraction.

Tokens
147.5K
Snippets
508
Records
665
Agent score
72%

What's inside gt

  1. Overview of @generaltranslation/format

    main

    The @generaltranslation/format package provides runtime-safe primitives for handling locales and string formatting within the General Translation ecosystem. It is designed to be a lightweight utility package for locale management and message formatting.

    Core capabilities include:

    • Locale Management: Normalization, validation, alias resolution, and matching.
    • Message Formatting: ICU and string message formatting.
    • Cutoff Formatting: Specialized formatting for cutoff values.
    • LocaleConfig: A wrapper utility that encapsulates locale and formatting helpers for easier use in applications.
  2. Overview of @generaltranslation/react-core

    main

    @generaltranslation/react-core is a pure React library designed for internationalization (i18n). It serves as the foundational logic layer for higher-level packages like gt-react and gt-next.

    Key characteristics:

    • Pure React: It focuses on React-specific i18n logic.
    • Runtime Agnostic: The package is designed to be agnostic of the specific runtime environment; compatibility with specific runtimes (like Next.js or React Native) is delegated to consumer packages.
  3. Overview of @generaltranslation/icu

    main

    The @generaltranslation/icu package provides dependency-free ICU MessageFormat primitives. It is designed to handle complex string localization tasks including parsing, AST manipulation, and formatting.

    Key capabilities include:

    • Parsing: ICU MessageFormat parsing that produces location-aware Abstract Syntax Trees (ASTs).
    • AST Printing: Capability to print ASTs to ensure stable hashing and support source transforms.
    • Interpolation & Logic: Support for string interpolation, select expressions, and cardinal/ordinal plurals.
    • Formatting: Leverages native Intl APIs for formatting numbers, dates, times, and ICU skeletons.

    Note on Dependencies: This package intentionally relies on the host environment's Intl implementation and does not include locale-data polyfills. Ensure your runtime environment has the necessary Intl support for your target locales.

  4. Overview of General Translation packages

    main

    General Translation provides various packages tailored to different frameworks and workflows:

    • gt-next: Automatic i18n for Next.js
    • gt-react: Automatic i18n for React
    • gt-i18n: Pure JavaScript i18n library
    • gt: CLI tool for continuous localization
    • gt-sanity: Plugin for Sanity Studio v3
    • locadex: AI agent for automating i18n in complex codebases
    • @generaltranslation/compiler: Build plugin for webpack, Vite, Rollup, and esbuild
    • @generaltranslation/mcp: MCP server for General Translation
    • @generaltranslation/react-core-linter: ESLint plugin for React Core integration
  5. Configure Field-Level Localization

    main

    The gt-sanity plugin supports field-level localization powered by sanity-plugin-internationalized-array. When translationLevel is set to 'internationalizedArray', documents are localized in place using internationalized arrays instead of per-locale documents.

    To use this, enable fieldLevelLocalization in the plugin config and specify the fieldTypes to be localized. You must then use the generated types in your schemas (e.g., type: 'internationalizedArrayString').

    gtPlugin({
      sourceLocale: 'en',
      locales: ['es', 'fr'],
      translateDocuments: ['post'],
      // Documents matched above are localized in place with
      // internationalized arrays instead of per-locale documents.
      translationLevel: 'internationalizedArray',
      fieldLevelLocalization: {
        enabled: true,
        fieldTypes: ['string', 'text'],
      },
    });
  6. How the compiler handles JSX auto-insertion of _T and _Var

    main

    The compiler automatically injects _T (translation) and _Var (variable) components into JSX to facilitate translation. The injection follows specific rules to ensure translatable text is captured without breaking component logic:

    • _T (Translation): Inserted at the highest level that directly contains translatable text. If a parent has direct text, it claims the entire subtree. Sibling elements without a common text parent receive independent _T wrappers.
    • _Var (Variable): Inserted around dynamic expressions (e.g., ternary operators or variables) that are part of a translatable string. Static or easily parseable expressions do not receive _Var.
    • Exclusions: _T is not inserted if there is no translatable string content (e.g., only numbers, only whitespace, or only non-text elements like <Var>). User-written <T>, <Var>, <Num>, <Currency>, and <DateTime> components are ignored by the auto-insertion logic.
    • Opaque Components: Components like <Branch> or <Plural> that appear inside a <Derive> context will receive their own independent _T wrapper and produce standalone hash entries.
    // Example of mixed insertion
    <div>Hello {name}</div>
    // Becomes:
    <div>
      <_T>Hello <_Var>{name}</_Var></_T>
    </div>
  7. Convert code to ICU format in auto-fixes

    main

    When converting dynamic expressions (concatenation or template literals) to ICU strings in an auto-fix, follow these rules:

    1. Variable Interpolation: Use {var0}, {var1}, etc., incrementing left-to-right. The options object maps these to the original expressions: { var0: expr0, var1: expr1 }.
    2. Select Statements (Ternaries): Use the format {varN, select, true {consequent} other {alternate}}. The condition becomes the variable value.
    3. String Concatenation: Walk the tree left-to-right, accumulating static parts and replacing dynamic parts with {varN} placeholders.
    4. Output Format: Always output a regular string literal ("..."), even if the input was a template literal. Use shorthand for the options object (e.g., { var0: name }).
  8. Configure the Sanity Translations Tab options

    main

    The Sanity integration provides default configuration options for the Translations Tab to handle the lifecycle of document translation between Sanity and a Translation Management System (TMS).

    There are two primary configuration hooks:

    1. exportForTranslation: A function used to process a Sanity document before it is sent to a TMS. By default, this serializes documents into HTML, where content is rendered within nested <div> elements in the HTML <body> and metadata is placed in the HTML <head>. This process relies on the Sanity Naive HTML Serializer.

    2. importTranslation: A function used to process a translated document received from a TMS. It parses the incoming data into a Sanity-readable format and patches it back to the original Sanity document. While it defaults to using the Sanity Naive HTML Serializer (assuming the TMS returned HTML), you can provide a custom function to handle different formats.

  9. Rule 6 & 7: How user-written GT components are handled

    main

    If a user manually writes GT components, the compiler pass treats them as opaque and performs no transformations on them or their descendants.

    Handled components:

    • <T> (User-written translation component)
    • <Var> (User-written variable component)
    • <Num> (User-written number component)
    • <Currency> (User-written currency component)
    • <DateTime> (User-written date/time component)

    Behavior:

    • The compiler sets an internal flag to suppress ALL transformations when entering these components.
    • This applies to all descendants, even if they are inside complex expressions like ternaries or function calls.
    • Note: This does NOT apply to _Var components auto-inserted by the compiler. JSX inside an auto-inserted _Var is still eligible for _T insertion.
    // User T is hands-off; other content in the same parent is still processed
    <div>
      <T>Translated</T>
      <span>Auto translate me</span>
    </div>
    // Result:
    <div>
      <T>Translated</T>
      <span><_T>Auto translate me</_T></span>
    </div>
    
    // User Var inside auto-translated content
    <div>Hello <Var>{name}</Var></div>
    // Result:
    <div><_T>Hello <Var>{name}</Var></_T></div>
    
    // Contrast: Auto-inserted Var allows internal _T insertion
    <div>Status: {isActive ? <span>Active</span> : <span>Inactive</span>}</div>
    // Result:
    <div><_T>Status: <_Var>{isActive ? <span><_T>Active</_T></span> : <span><_T>Inactive</_T></span>}</_Var></_T></div>
  10. How regular component props are processed

    main

    For standard components (those that are not GT opaque components like Branch, Plural, or Derive), JSX in non-children props (such as header, icon, or footer) is treated as an independent subtree. The translation pass processes these props separately, meaning the _T state from the parent does not carry over into these props.

    Example: If a <Card> has a header prop containing text, the header content will receive its own _T insertion, independent of the children content.

    // header prop has its own JSX — processed independently
    <Card header={<h1>Title</h1>}>Body text</Card>
    // Result:
    <Card header={<h1><_T>Title</_T></h1>}><_T>Body text</_T></Card>
  11. How JSX auto-insertion of _T and _Var works

    main

    The GT compiler plugin automatically wraps translatable JSX content in GtInternalTranslateJsx (_T) and dynamic expressions in GtInternalVar (_Var) during the build process. This process operates on compiled JSX (after Vite/SWC transforms).

    To ensure successful translation resolution at runtime, two systems must implement these rules identically:

    1. The compiler plugin: Physically inserts _T and _Var into the JSX tree at build time.
    2. The CLI registration tool: Simulates these insertions to compute hashes for translatable content.

    If these systems disagree on where wrappers are placed, the computed hashes will mismatch, causing translation failures.

    /* The process happens automatically at build time on compiled JSX */