Internationalization
The SDK ships translation bundles for pt-BR (default), en, and
es. Strings cover everything that's hardcoded in the chat UI:
header title, placeholder, empty state, loading status, breadcrumb
action labels, human-escalation copy, "Powered by", a11y labels.
pt-BR is the SDK's own runtime default when no locale can be
resolved — unrelated to this documentation site's default locale
(this site defaults to English).
Switching locale
<AppilotsChat locale="es" />
When locale is omitted the SDK tries the device locale via
detectDeviceLocale() and falls back to pt-BR if the device
language doesn't match a bundled locale. The dashboard's
Personalização → Idioma padrão field overrides the fallback at
the project level.
Reading strings in custom UI
If you build your own components on top of the SDK and want them to
match the active locale, mount them under the same <AppilotsChat />
or wrap them in <AppilotsI18nProvider>:
import { AppilotsI18nProvider, useAppilotsI18n } from '@appilots/sdk';
function MyHelp() {
const { t, locale, strings } = useAppilotsI18n();
return <Text>{t('emptySubtitle')}</Text>;
}
<AppilotsI18nProvider locale="en">
<MyHelp />
</AppilotsI18nProvider>;
Per-key overrides
Want to ship most strings in English but say "Made by ACME" in the
footer? Pass an overrides map:
<AppilotsI18nProvider
locale="en"
overrides={{ poweredBy: 'Made by ACME' }}
>
<AppilotsChat />
</AppilotsI18nProvider>
Adding a new locale
- Create
packages/sdk/src/i18n/bundles/<locale>.tswith every key fromAppilotsStringsfilled in (TypeScript will refuse to build if a key is missing). - Register the bundle in
packages/sdk/src/i18n/I18nProvider.tsx(BUNDLESmap and theAppilotsLocaleunion). - Add the locale to
localeSchemain@appilots/shared/validatorsso it's accepted by the dashboard. - (Optional) Update
detectDeviceLocale()to map device language codes onto the new locale.
Available keys
import type { AppilotsStrings } from '@appilots/sdk';
interface AppilotsStrings {
/** Default chat header title when the dev hasn't supplied one. */
chatTitle: string;
/** Header button that wipes the conversation. */
clearButton: string;
/** Placeholder for the message input. */
inputPlaceholder: string;
/** Empty state heading. */
emptyTitle: string;
/** Empty state subtitle / one-liner under the heading. */
emptySubtitle: string;
/** "Thinking..." placeholder shown while the assistant is replying. */
thinking: string;
/** Status shown while the assistant is planning from the current screen. */
statusAnalyzing: string;
/** Status shown while the SDK waits for the app to settle after an action. */
statusWaitingApp: string;
/** Status shown while the assistant adjusts after a recoverable failure. */
statusAdjusting: string;
/** Footer line shown when poweredByVisible !== false. */
poweredBy: string;
/** Approve button on a pending action row in the breadcrumb. */
approve: string;
/** Reject button on a pending action row in the breadcrumb. */
reject: string;
/** Generic "cancelled by the user" message after a reject. */
cancelledByUser: string;
/** Fallback humanised name for an unknown action type. */
unknownAction: string;
/** Generic friendly error when nothing else fits. */
somethingWentWrong: string;
/** Open chat accessibility label for the floating bubble. */
openChatA11y: string;
/** Close chat accessibility label. */
closeChatA11y: string;
/** A11y label for the stop-generation button. */
stopGeneratingA11y: string;
/** A11y label for the "talk to a human" header button. */
talkToHumanA11y: string;
/** Sender label above a human operator's bubble. */
humanAgentLabel: string;
/** System line right after the user (or the offer chip) escalates. */
escalationRequested: string;
/** System line when an operator claims the conversation. */
escalationConnected: string;
/** System line when the operator resolves — AI takes over again. */
escalationResolved: string;
/** System line offering the handoff after the agent gives up. */
escalationOffer: string;
/** Label of the tappable chip under the offer line. */
escalationOfferChip: string;
/** Thin banner under the header while waiting in the queue. */
escalationPendingBanner: string;
/** Thin banner under the header while connected to an operator. */
escalationActiveBanner: string;
}