Features
Localization that behaves like an engineering tool and reads like plain language
Bobby Translate is built around one rule: nothing is written, overwritten or published without an explicit, reviewable decision.
Import
Bring your existing files — safely
Import is a first-class product surface, not an afterthought. Detection, mapping and a full preview happen before a single value is stored.
What Bobby Translate detects for you
- File format, from content and not from the extension alone
- Encoding, including UTF-8 byte-order marks and suspected UTF-16
- Locale, from filename, folder, or in-file metadata such as @@locale
- Namespace hints, without swallowing the locale segment
- Nested versus flat key structure, and duplicate keys
- Plural forms, placeholders and HTML-bearing values
- Empty values, which are reported as missing rather than translated
What Bobby Translate refuses to do
- Guess a format when structured content fails to parse
- Parse executables, binaries, PDFs or script payloads
- Follow archive paths that escape their own folder (zip-slip)
- Expand archives with implausible compression ratios (zip bombs)
- Silently drop malformed rows — they are listed, with line numbers
- Write anything before you accept the preview
Format matrix
Detection covers every format below. Parsing is implemented where marked; where it is not, Bobby Translate says so instead of producing an approximate reading.
| Format | Typical files | Structure | Parser |
|---|---|---|---|
| JSON (nested) | .json | plurals | implemented |
| JSON (flat) | .json | implemented | |
| ARB (Flutter) | .arb | plurals · comments · @@locale and @key metadata are read as locale hint, description and placeholders. | implemented |
| YAML / YML | .yaml .yml | plurals · comments · Indentation-based subset: scalars, nesting and comments. Anchors and multi-document files are rejected rather than guessed. | implemented |
| Rails locale YAML | .yml | plurals · comments · Top-level locale key is detected and stripped into the locale mapping. | implemented |
| CSV | .csv | comments · multi-locale · Interactive column mapping is mandatory. | implemented |
| TSV | .tsv .tab | comments · multi-locale · Interactive column mapping is mandatory. | implemented |
| XLIFF 1.2 | .xlf .xliff | comments | implemented |
| XLIFF 2.x | .xlf .xliff | comments | implemented |
| GNU gettext PO / POT | .po .pot | plurals · comments | implemented |
| Android XML resources | .xml | plurals · comments | implemented |
| Apple .strings | .strings | comments | implemented |
| Java .properties | .properties | comments | implemented |
| .NET RESX | .resx | comments | implemented |
| Fluent FTL | .ftl | plurals · comments · Simple messages and comments. Selectors are imported as raw source and flagged for review. | implemented |
| Generic key/value text | .txt .ini .conf | comments · Only when a safe key=value mapping can be inferred with confidence. | implemented |
| Apple .stringsdict | .stringsdict | plurals · Detected and rejected with an explanation. Plural-rule mapping needs its own design pass. | detect only |
| iOS/macOS .xcstrings | .xcstrings | plurals · comments · multi-locale · Detected only. Multi-locale catalogue mapping is Phase 2B. | detect only |
| PHP arrays | .php | comments · Detected only. Must be parsed as data, never evaluated. | detect only |
| Gettext MO (binary) | .mo | plurals · Only if safely decoded server-side. Not implemented. | detect only |
Translate
Machine first, human where it matters
Every language pair can be handled by a primary engine, cross-checked by a second engine, or assigned to a real translator.
Primary translation
One configured engine produces a suggestion for every missing or outdated value. Suggestions are stored as suggestions — they never enter a published state on their own.
Second opinion
Optionally run a different engine over the same string and compare the two side by side. Disagreement is a useful signal about which strings deserve a human.
Human translation
Assign a language pair to a translator, who works in a dedicated workbench with the source, the suggestions, the glossary and the context in view.
Review
One status vocabulary, with defined transitions
Every value has exactly one status, and every change from one status to another is enumerated rather than implied.
| Status | Can move to |
|---|---|
| Missing | Draft, Machine suggested, Human assigned, Blocked |
| Draft | Machine suggested, Human assigned, In review, Blocked, Archived |
| Machine suggested | Second opinion requested, Human assigned, In review, Draft, Blocked |
| Second opinion requested | Machine suggested, In review, Human assigned, Blocked |
| Human assigned | Human translated, Blocked, Draft |
| Human translated | In review, Changes requested, Approved, Blocked |
| In review | Changes requested, Approved, Blocked |
| Changes requested | Human translated, Draft, In review, Blocked |
| Approved | Published, Outdated, In review, Archived |
| Published | Outdated, In review, Archived |
| Outdated | Draft, Machine suggested, Human assigned, In review |
| Blocked | Draft, Archived |
| Archived | Draft |
Approved human translations are never replaced by machine output. When the source string changes, dependent translations become outdated rather than silently wrong.
Coverage
What counts as translatable content
- Interface strings
- Website and CMS pages
- Content sections
- Navigation and forms
- Emails and notifications
- Errors and system messages
- Product descriptions
- Help-center content
- SEO titles and meta descriptions
- Open Graph copy
- Structured-data text
- Image alternative text
- Slugs, only when explicitly enabled
- Locale and hreflang configuration
- Application translation keys
- Localization files
- Bobby CMS content and metadata
Maturity of what you just read
Import detection, archive safety, mapping and preview are implemented and covered by automated tests. Committing an import into a stored project is designed but not built.
No translation provider is connected, so no machine suggestion or second opinion can be produced today, and no customer text leaves your browser in this phase.