I18nId Specification
Overview
Section titled “Overview”The I18nId v1 specification defines how strings are converted to deterministic, collision-resistant identifiers for internationalization.
Format
Section titled “Format”i18n:v1:<hash>Where:
i18n- Protocol identifierv1- Specification version<hash>- BLAKE3 hash of normalized string (hex encoded, 16 characters)
Examples
Section titled “Examples”| Source String | I18nId |
|---|---|
| ”Hello” | i18n:v1:a5b9c3d7e8f0 |
| ”Hello, World!” | i18n:v1:b6c8d4e9f1a2 |
| ” Hello “ | i18n:v1:a5b9c3d7e8f0 (same after normalization) |
Normalization
Section titled “Normalization”Before hashing, strings are normalized:
- Trim whitespace - Remove leading/trailing spaces
- Collapse internal whitespace - Multiple spaces → single space
- Unicode normalization - NFC form
- Lowercase (optional, configurable)
fn normalize(input: &str) -> String { input .trim() .split_whitespace() .collect::<Vec<_>>() .join(" ")}Hash Generation
Section titled “Hash Generation”use blake3::Hasher;
fn generate_i18n_id(text: &str) -> String { let normalized = normalize(text); let hash = blake3::hash(normalized.as_bytes()); let hex = hex::encode(&hash.as_bytes()[..8]); // First 8 bytes = 16 hex chars format!("i18n:v1:{}", hex)}Properties
Section titled “Properties”Deterministic
Section titled “Deterministic”Same input always produces same output:
assert_eq!( generate_i18n_id("Hello"), generate_i18n_id("Hello"));Collision Resistant
Section titled “Collision Resistant”BLAKE3 with 64 bits provides ~2^32 birthday resistance, suitable for most applications.
Stable
Section titled “Stable”IDs remain stable across:
- Different platforms
- Different programming languages
- Different versions (within v1)
Usage in Greentic
Section titled “Usage in Greentic”Flow Messages
Section titled “Flow Messages”- id: greet type: reply config: message_key: "i18n:v1:a5b9c3d7e8f0"{ "type": "TextBlock", "text": "{{i18n:i18n:v1:a5b9c3d7e8f0}}"}Templates
Section titled “Templates”{{t "i18n:v1:a5b9c3d7e8f0"}}CLI Tools
Section titled “CLI Tools”Generate ID
Section titled “Generate ID”greentic-i18n id "Hello, World!"# Output: i18n:v1:b6c8d4e9f1a2Verify ID
Section titled “Verify ID”greentic-i18n verify "i18n:v1:b6c8d4e9f1a2" "Hello, World!"# Output: ValidMigration from Other Systems
Section titled “Migration from Other Systems”From Key-Based
Section titled “From Key-Based”// Before{ "greeting.hello": "Hello" }
// After (auto-migration){ "i18n:v1:a5b9c3d7e8f0": "Hello" }Migration Script
Section titled “Migration Script”greentic-i18n migrate ./old-translations.json --output ./new-translations.jsonBest Practices
Section titled “Best Practices”- Always use the CLI to generate IDs
- Don’t modify IDs manually - regenerate if source changes
- Store source strings alongside translations for reference
- Version your translation files - enables rollback
- Test with multiple locales - catch missing translations