🔀 Multi-provider Architecture
Translation is no longer coupled to a single endpoint. A TranslateProvider interface now abstracts each backend, making it easy to add or swap providers without touching the UI layer:
- Providers are registered in a central map and exposed to the UI through
TRANSLATE_PROVIDERS. - The user selects a provider from a dropdown in the form; the choice persists in
localStorage. - If a provider fails mid-route, the user can switch to another provider and resume from the failed round without re-running successful steps.
- Adding a new provider requires only implementing the
TranslateProviderinterface and registering it inPROVIDERS+TRANSLATE_PROVIDERS.
🆕 MyMemory Provider
A new MyMemory provider is now available alongside Google Translate:
- Powered by the MyMemory free translation memory API — no API key required and CORS wide open (
*). - Ideal as a fallback when Google’s free endpoints hit rate limits or region restrictions.
- Handles the
autosource-language case by passingautodetectto the API. - Shares the same retry and backoff logic as all providers.
Note: MyMemory has a per-IP daily character quota (~5 000 chars) and translation quality depends on memory hits; less common language pairs may return untranslated or partially translated text. Microsoft/Bing endpoints (require credentials or lack CORS) and Baidu/DeepL (require keys) cannot be called from the browser and are not included.
🛡️ Resilient Translation Pipeline
The shared fetchWithRetry utility now underpins every provider:
- Exponential backoff with jitter across up to 3 attempts per endpoint.
- Retryable HTTP status codes:
0(network),403,429,500,502,503,504. - Google’s three endpoint hosts rotate automatically before giving up.
- Structured
TranslateErrorwith machine-readable codes (network_error,api_error,empty_result,unavailable) map to localized UI messages.
⏩ Resume-from-Failure
When a translation round fails:
- Completed rounds are preserved in the UI.
- A “Resume” button appears, letting the user switch providers and continue from the exact round that failed.
- History is only saved on full completion, so partial runs don’t clutter the list.
🌍 UI and Localization
- A provider selector dropdown has been added to the translation form.
- New localized message keys:
provider.google,provider.mymemory,status.providerFailed,status.providerSwitched. - All six supported locales have been updated with the new strings.