awaitForTranslationOrFallbackToOriginal()
awaitForTranslationOrFallbackToOriginal is the translation method for request-time code:
HTTP route handlers, server components, generateMetadata, API responses, emails, push
notifications. It looks up (and fetches, if missing) the translated text for a target
language, and never rejects — a failed request falls back to the original text instead of
taking down the request that asked for it.
awaitForTranslationOrFallbackToOriginal MUST be awaited to prevent 429 rate limit errors.
Even though it never rejects, i18n-keyless-node POSTs directly with no queue — a
fire-and-forget call still hits the API's rate limit.
Function Signature
awaitForTranslationOrFallbackToOriginal(
text: string,
language: Lang,
options?: {
context?: string;
namespace?: string;
unpersistedNamespace?: boolean;
replace?: Record<string, string>;
forceTemporary?: Partial<Record<Lang, string>>;
originLanguage?: Lang;
debug?: boolean;
}
): Promise<string>
Parameters
text
type: string(required)
The text to be translated. This text serves as both the display content and the translation key.
language
type: Lang(required)
The target language code for translation. Must be one of the 48 Lang
codes — "fr", "en", "es", "zh-Hans", "pt-BR", and so on.
options
type: object(optional)
Configuration object with the following optional properties:
context
type: string(optional)
Additional context to help ensure accurate translations. Useful when the same text might have different meanings in different situations.
namespace
type: string(optional)
Fetch partition this translation belongs to — the backend returns only the requested namespace. Defaults to defaultNamespace from init(), or "default". See the Namespaces guide.
unpersistedNamespace
type: boolean(optional)
Marks the namespace as transient. Mainly a client-storage flag (on i18n-keyless-react it keeps the namespace out of storage); harmless on Node.
replace
type: Record<string, string>(optional)
Object for replacing placeholders in the text with dynamic values. Common patterns: {name}, [value], %user%, etc. Also applied to the fallback text when the POST fails — see Failure behaviour below.
forceTemporary
type: Partial<Record<Lang, string>>(optional)
Override the AI-generated translation with your own, keyed by target language:
{ forceTemporary: { en: "Go Back" } }. Useful while a translation is wrong and you don't want to wait for it to be regenerated.
originLanguage
type: Lang(optional)
Set when text is user-generated content written in a language other than your primary
language. See the User-Generated Content guide.
debug
type: boolean(optional)
Enable console logging for debugging translation behavior.
Basic Usage
- Simple Translation
- With Context
- With Replacements
- Force Translation
- Batch Processing
import { awaitForTranslationOrFallbackToOriginal, type Lang } from 'i18n-keyless-node';
async function sendNotifications() {
const users = await fetchUsers();
for (const user of users) {
const title = await awaitForTranslationOrFallbackToOriginal(
"Come see my app!",
user.lang as Lang
);
const body = await awaitForTranslationOrFallbackToOriginal(
"So many new features!",
user.lang as Lang
);
await sendNotification(user, { title, body });
}
}
import { awaitForTranslationOrFallbackToOriginal, type Lang } from 'i18n-keyless-node';
async function generateEmailContent(user: User) {
const subject = await awaitForTranslationOrFallbackToOriginal(
"Welcome to our platform",
user.language as Lang,
{ context: "This is an email subject line" }
);
const greeting = await awaitForTranslationOrFallbackToOriginal(
"Back",
user.language as Lang,
{ context: "This is a back button in navigation" }
);
return { subject, greeting };
}
import { awaitForTranslationOrFallbackToOriginal, type Lang } from 'i18n-keyless-node';
async function personalizedMessage(user: User) {
const message = await awaitForTranslationOrFallbackToOriginal(
"Hello {name}, welcome to {platform}!",
user.language as Lang,
{
replace: {
'{name}': user.name,
'{platform}': 'i18n-keyless'
}
}
);
return message;
}
import { awaitForTranslationOrFallbackToOriginal, type Lang } from 'i18n-keyless-node';
async function customTranslation(targetLang: Lang) {
const text = await awaitForTranslationOrFallbackToOriginal(
"Retour",
targetLang,
{ forceTemporary: { en: "Go Back" } }
);
return text;
}
import { awaitForTranslationOrFallbackToOriginal, type Lang } from 'i18n-keyless-node';
async function translateBatch(texts: string[], targetLang: Lang) {
const translations = [];
for (const text of texts) {
const translated = await awaitForTranslationOrFallbackToOriginal(text, targetLang);
translations.push(translated);
// Small delay to respect rate limits
await new Promise(resolve => setTimeout(resolve, 100));
}
return translations;
}
Common Use Cases
- Request handlers: HTTP routes, server components, and
generateMetadata, where one failed translation must not fail the whole response - Email templates: Translating email subjects and content for international users
- Push notifications: Sending localized notifications to mobile app users
- API responses: Returning translated content without risking a 500 on a network hiccup
- Server-side rendering: Pre-translating content for specific markets at request time
For a build step, a CLI script, or a migration — where a failed translation should stop the
run instead of shipping source text — use
awaitForTranslationOrThrow instead.
Failure behaviour
awaitForTranslationOrFallbackToOriginal never rejects. When the POST fails (network error,
a not-ok API answer, or a custom handleTranslate throw), it resolves to the original text
— the key as written, with replace applied — exactly like a miss already resolves when the
API has no text for that language. "Original" means the primary-language text, or the
origin-language text for a UGC call carrying originLanguage.
The failure is still logged with console.error, naming the key, so a translation that
silently fell back stays visible in your logs even though nothing rejected.
No try/catch is needed around it. Use awaitForTranslationOrThrow
instead when a failure must stop the run — a build step or a script, for example.
Rate Limiting
- MUST be awaited to prevent 429 (Too Many Requests) errors, even though it never rejects
- i18n-keyless handles caching, throttling, debouncing - no worries, as long as you await
- The service has built-in rate limiting to ensure optimal performance
Related
- awaitForTranslationOrThrow() - the throwing variant, for scripts and build steps
- awaitForTranslation() (deprecated) - the old, single-behaviour alias
- I18nKeyless.init() - Initialize the library
- Types - Type definitions