Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
243 changes: 243 additions & 0 deletions packages/cli/PSEUDO_LOCALIZATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
# Pseudo-Localization Mode

## Overview

Pseudo-localization is a testing technique that helps developers verify that their applications are ready for internationalization (i18n) without waiting for actual translations. Instead of using real translated text, pseudo-localization automatically replaces characters with accented versions and adds visual markers.

This is a standard practice used by Google, Microsoft, and Mozilla in their localization pipelines.

## When to Use

Pseudo-localization is ideal for:

- **Early UI Testing**: Test your UI before translations are complete
- **Layout Issue Detection**: Identify truncation, overflow, and text expansion problems
- **CI/CD Integration**: Validate i18n readiness in continuous integration pipelines
- **Development Workflow**: Catch i18n issues before deployment
- **Rapid Iteration**: Quickly test UI changes without external API calls

## Usage

### Via CLI

Run the localization pipeline in pseudo-localization mode:

```bash
pnpx lingo.dev run --pseudo
```

This will:

1. Extract all translatable strings from your source code
2. Pseudo-translate them by replacing characters with accented versions
3. Write the pseudo-translated strings to your target locale files
4. Mark each pseudo-translation with a **⚡** symbol for easy identification

### Example

**Input files:**
```jsx
// app.jsx
<>
<h1>Submit</h1>
<p>Welcome back!</p>
</>
```

**Output with `--pseudo` flag:**
```json
// en-XA/messages.json
{
"submit": "Šûbmíţ⚡",
"welcome_back": "Ŵèļçømèƀäçķ!⚡"
}
```

## How It Works

### Character Replacement

Each ASCII letter is replaced with a visually similar accented character:

| Original | Replacement | Original | Replacement |
|----------|-------------|----------|-------------|
| a | ã | A | Ã |
| e | è | E | È |
| i | í | I | Í |
| o | ø | O | Ø |
| u | û | U | Û |
| s | š | S | Š |
| t | ţ | T | Ţ |

And so on for all letters. Non-alphabetic characters (numbers, punctuation, spaces) are preserved as-is.

### Visual Marker

A ⚡ symbol is appended to each pseudo-translated string, making it immediately visible which text has been pseudo-localized.

## Configuration

Currently, pseudo-localization only supports the `--pseudo` CLI flag. Support for configuration in `i18n.json` is planned for a future release.

## Key Features

✅ **No External API Calls**: Run completely offline
✅ **Instant Feedback**: Pseudo-translate instantly without waiting
✅ **Character Replacement**: Uses accent-based character mapping (en-XA style)
✅ **Visual Markers**: Easy to identify pseudo-translated strings
✅ **Recursive Object Handling**: Works with nested structures and arrays
✅ **Preserves Structure**: Maintains JSON/object structure and types

## What Pseudo-Localization Tests

### ✅ Catches These Issues

- **Text Truncation**: UI elements that cut off text
- **Layout Overflow**: Components that break with longer text
- **Font Support**: Missing glyph support for special characters
- **Text Direction**: Issues with RTL content (though accents don't change direction)
- **String Concatenation**: Hardcoded text that should be translatable
- **Placeholder Text**: Missing localization in form fields or labels

### ❌ Does NOT Replace

- **Actual Translation**: Pseudo-localization is for testing, not production use
- **Translation Memory**: Use Lingo.dev or other providers for real translations
- **Quality Assurance**: Manual review of actual translations is still needed
- **Cultural Adaptation**: Different cultures have different needs beyond character replacement

## Advanced Usage

### Combining with Other Flags

```bash
# Pseudo-localize only specific locales
pnpx lingo.dev run --pseudo --target-locale es --target-locale fr

# Pseudo-localize only specific buckets
pnpx lingo.dev run --pseudo --bucket json --bucket yaml

# Pseudo-localize specific files
pnpx lingo.dev run --pseudo --file messages.json --file labels.json

# Force re-pseudo-translation
pnpx lingo.dev run --pseudo --force
```

### With Watch Mode

```bash
# Automatically pseudo-translate when files change
pnpx lingo.dev run --pseudo --watch
```

## Implementation Details

### Locale Code Convention

Pseudo-localized content uses the special locale code `en-XA` (following Google's convention), where:
- **en** = English (source language)
- **XA** = Pseudo-Accents

This is recognized by many i18n libraries and tools.

### API Usage

For programmatic use, the pseudo-localization functions are available:

```typescript
import { pseudoLocalize, pseudoLocalizeObject } from "lingo.dev/utils";

// Pseudo-localize a single string
const result = pseudoLocalize("Hello World");
// Result: "Ĥèļļø Ŵøŕļð⚡"

// Pseudo-localize an entire object
const messages = { greeting: "hello", farewell: "goodbye" };
const pseudoMessages = pseudoLocalizeObject(messages);
// Result: { greeting: "ĥèļļø⚡", farewell: "ĝøøðßýè⚡" }
```

## Troubleshooting

### My UI still looks fine with pseudo-localization

This might indicate:

- **Hardcoded strings**: Some text might not be extracted properly. Check your extraction configuration.
- **Flexible layouts**: Your UI might be designed to handle text expansion. Good news for i18n!
- **Font issues**: Ensure your font supports accented characters. Test with a web-safe font first.

### The ⚡ marker is being cut off

This is exactly what pseudo-localization is meant to catch! It means:

- Your UI has truncation issues with longer text
- You need to expand text containers or reduce font size for translations
- Consider using `max-width` or `line-clamp` CSS properties carefully

### I want to customize the character mapping

Currently, character mapping is fixed to the en-XA style. For custom mappings, you can use the library functions directly and modify the mapping as needed.

## Examples

### React Component Testing

```jsx
// Before pseudo-localization
<button>{t("submit")}</button>

// After pseudo-localization
<button>Šûbmíţ⚡</button>

// You'll immediately see if the button is too small!
```

### Form Labels

```jsx
// Before
<label>{t("email")}</label>

// After (pseudo-localized)
<label>èmãíļ⚡</label>

// Check for proper alignment and spacing
```

## Performance

Pseudo-localization is extremely fast:

- **No network requests**: Everything happens locally
- **Minimal processing**: Simple character replacement
- **Instant results**: Suitable for development and CI/CD

## Comparison with Alternatives

| Method | Speed | Accuracy | Cost | Configuration |
|--------|-------|----------|------|---------------|
| Pseudo-localization | ⚡ Instant | Simulates expansion | Free | CLI flag only |
| AI Translation | ⏱️ Seconds | Good (OpenAI, etc.) | $ | API key required |
| Human Translation | 🐢 Days | Excellent | $$$$ | Translation service |

## Related Resources

- [Google's Pseudo-translation](https://google.github.io/styleguide/tsqm.html)
- [Mozilla's Pseudo-localization](https://mozilla-l10n.github.io/documentation/tools/pseudo/)
- [i18n Best Practices](https://www.w3.org/International/questions/qa-i18n)

## Next Steps

After pseudo-localizing:

1. **Test your UI**: Navigate your application with pseudo-localized content
2. **Identify issues**: Look for truncated text, overflows, or layout problems
3. **Fix UI**: Adjust CSS, layouts, or text containers as needed
4. **Run actual translations**: Once UI is i18n-ready, use Lingo.dev with real translations
5. **Deploy with confidence**: Your app is now ready for international users!

## Feedback & Issues

Found a bug or have a feature request? Open an issue on [GitHub](https://github.com/LingoDotDev/lingo.dev).
146 changes: 146 additions & 0 deletions packages/cli/PSEUDO_LOCALIZATION_QUICK_START.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Pseudo-Localization Quick Start Guide

## Installation

The pseudo-localization feature is built into Lingo.dev CLI. No additional installation needed!

## Quick Commands

### Test a single locale
```bash
pnpx lingo.dev run --pseudo
```

### Test specific locales
```bash
pnpx lingo.dev run --pseudo --target-locale es --target-locale fr
```

### Watch mode (auto-pseudo-translate on file changes)
```bash
pnpx lingo.dev run --pseudo --watch
```

### Force re-pseudo-translation
```bash
pnpx lingo.dev run --pseudo --force
```

### Filter by file pattern
```bash
pnpx lingo.dev run --pseudo --file messages.json
```

### Filter by key prefix
```bash
pnpx lingo.dev run --pseudo --key "auth.login"
```

## Example Output

### Before
```json
{
"welcome": "Welcome back!",
"submit": "Submit",
"cancel": "Cancel"
}
```

### After (with `--pseudo`)
```json
{
"welcome": "Ŵèļçømèƀãçķ!⚡",
"submit": "Šûbmíţ⚡",
"cancel": "Çãñçèļ⚡"
}
```

## What You'll Notice

✅ **Text is longer** - Many languages are longer than English (20-30% common)
✅ **Characters look weird** - Accented characters help spot untranslated strings
✅ **⚡ marker visible** - Easy to see what's pseudo-localized
✅ **Spacing issues appear** - Reveals layout problems immediately

## Common Use Cases

### Before Translations Arrive
```bash
# Start development with pseudo-localization
pnpx lingo.dev run --pseudo

# Test your UI with the pseudo-translated files
npm run dev

# Fix any layout issues you find
# When real translations arrive, just switch to real provider
pnpx lingo.dev run # Uses configured provider
```

### In CI/CD
```yaml
# .github/workflows/i18n.yml
name: Validate i18n
on: [push]

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npx lingo.dev run --pseudo --frozen
# --frozen ensures nothing needs translating
```

### Testing UI Component Libraries
```bash
# Test components with pseudo-localized strings
pnpx lingo.dev run --pseudo --bucket json

# Build Storybook with pseudo-localized strings
npm run build-storybook
```

## Troubleshooting

### "Pseudo-localization is enabled but I don't see the ⚡"

Check if your strings are being extracted correctly:
```bash
pnpx lingo.dev run --verbose --pseudo
```

### "Text is being truncated badly"

This is exactly what pseudo-localization should catch! 🎯

Solutions:
- Increase container width/height
- Use flexible layouts (flexbox, grid)
- Set `word-wrap: break-word` in CSS
- Avoid hardcoded width/height values

### "Some strings aren't showing up pseudo-localized"

Possible causes:
- String not marked for i18n in code
- String in a component that's not being processed
- String in a comment or non-extractable location

Use `--verbose` flag to see what's being extracted.

## Next Steps

1. **Test your UI** - Navigate your app with pseudo-localized strings
2. **Fix issues** - Address any layout or truncation problems
3. **Switch to real translations** - Remove `--pseudo` flag when ready
4. **Deploy with confidence** - Your app is now ready for international users!

## More Information

- 📖 [Full Documentation](./PSEUDO_LOCALIZATION.md)
- 🐛 [Report Issues](https://github.com/LingoDotDev/lingo.dev/issues)
- 💬 [Ask Questions](https://lingo.dev/go/discord)
- ⭐ [Give us a star!](https://github.com/LingoDotDev/lingo.dev)
Loading
Loading