Skip to main content

Internationalization (i18n)

Customize all UI strings in DialStack components for localization or branding.

Quick Start

import { en } from '@dialstack/sdk/locales';

// Create French locale
const fr = {
...en,
common: {
...en.common,
loading: 'Chargement...',
error: 'Erreur',
noResults: 'Aucun résultat',
},
callLogs: {
...en.callLogs,
title: 'Journal des appels',
empty: 'Aucun appel trouvé',
},
};

<CallLogs locale={fr} />;

Locale Structure

The locale object has three main sections:

interface Locale {
common: CommonStrings;
voicemails: VoicemailStrings;
callLogs: CallLogStrings;
}

Common Strings

Shared across all components:

interface CommonStrings {
loading: string; // 'Loading...'
error: string; // 'Error'
noResults: string; // 'No results'
delete: string; // 'Delete'
call: string; // 'Call'
cancel: string; // 'Cancel'
confirm: string; // 'Confirm'
previous: string; // 'Previous'
next: string; // 'Next'
perPage: string; // 'Per page'
showing: string; // 'Showing {start}-{end} of {total}'
play: string; // 'Play'
pause: string; // 'Pause'
}

Voicemail Strings

interface VoicemailStrings {
title: string; // 'Voicemails'
loading: string; // 'Loading voicemails...'
empty: string; // 'No voicemails'
noUserId: string; // 'Please set a user ID to load voicemails'
transcription: string; // 'Transcription'
deleteConfirm: string; // 'Delete this voicemail?'
deleteTitle: string; // 'Delete Voicemail'
progress: string; // 'Playback progress'
}

Call Log Strings

interface CallLogStrings {
title: string; // 'Call Logs'
loading: string; // 'Loading call logs...'
empty: string; // 'No call logs found'
columns: {
date: string; // 'Date'
direction: string; // 'Direction'
from: string; // 'From'
to: string; // 'To'
duration: string; // 'Duration'
status: string; // 'Status'
};
directions: {
inbound: string; // 'Inbound'
outbound: string; // 'Outbound'
internal: string; // 'Internal'
};
statuses: {
completed: string; // 'Completed'
noAnswer: string; // 'No Answer'
busy: string; // 'Busy'
failed: string; // 'Failed'
voicemail: string; // 'Voicemail'
};
}

Built-in Locales

Currently, English is the only built-in locale:

import { en } from '@dialstack/sdk/locales';

Creating Custom Locales

Full Custom Locale

import type { Locale } from '@dialstack/sdk/locales';

const de: Locale = {
common: {
loading: 'Laden...',
error: 'Fehler',
noResults: 'Keine Ergebnisse',
delete: 'Löschen',
call: 'Anrufen',
cancel: 'Abbrechen',
confirm: 'Bestätigen',
previous: 'Zurück',
next: 'Weiter',
perPage: 'Pro Seite',
showing: 'Zeige {start}-{end} von {total}',
play: 'Abspielen',
pause: 'Pause',
},
voicemails: {
title: 'Sprachnachrichten',
loading: 'Sprachnachrichten werden geladen...',
empty: 'Keine Sprachnachrichten',
noUserId: 'Bitte setzen Sie eine Benutzer-ID',
transcription: 'Transkription',
deleteConfirm: 'Diese Sprachnachricht löschen?',
deleteTitle: 'Sprachnachricht löschen',
progress: 'Wiedergabefortschritt',
},
callLogs: {
title: 'Anrufliste',
loading: 'Anrufliste wird geladen...',
empty: 'Keine Anrufe gefunden',
columns: {
date: 'Datum',
direction: 'Richtung',
from: 'Von',
to: 'An',
duration: 'Dauer',
status: 'Status',
},
directions: {
inbound: 'Eingehend',
outbound: 'Ausgehend',
internal: 'Intern',
},
statuses: {
completed: 'Abgeschlossen',
noAnswer: 'Keine Antwort',
busy: 'Besetzt',
failed: 'Fehlgeschlagen',
voicemail: 'Sprachnachricht',
},
},
};

Extending English Locale

Override only specific strings:

import { en } from '@dialstack/sdk/locales';

const customEn = {
...en,
common: {
...en.common,
noResults: 'Nothing to show',
},
callLogs: {
...en.callLogs,
title: 'Call History',
empty: 'No calls yet',
},
};

Partial Override

Override only the section you need:

import { en } from '@dialstack/sdk/locales';

const brandedLocale = {
...en,
voicemails: {
...en.voicemails,
title: 'Messages',
empty: 'Your inbox is empty',
},
};

Using Locales

Per-Component

<CallLogs locale={customLocale} />
<Voicemails userId="user_123" locale={customLocale} />

With Web Components

const callLogs = document.querySelector('dialstack-call-logs');
callLogs.setLocale(customLocale);

Dynamic Locale Switching

Change locale at runtime:

function Dashboard() {
const [locale, setLocale] = useState(en);

return (
<div>
<select onChange={(e) => setLocale(locales[e.target.value])}>
<option value="en">English</option>
<option value="fr">Français</option>
<option value="de">Deutsch</option>
</select>

<CallLogs locale={locale} />
<Voicemails userId="user_123" locale={locale} />
</div>
);
}

Interpolation

Some strings support placeholders:

// 'showing' uses {start}, {end}, {total}
showing: 'Showing {start}-{end} of {total}';

// Result: "Showing 1-20 of 150"

Complete Example

import { useState } from 'react';
import { initialize, DialstackComponentsProvider, CallLogs, Voicemails } from '@dialstack/sdk';
import { en } from '@dialstack/sdk/locales';
import type { Locale } from '@dialstack/sdk/locales';

// Define locales
const locales: Record<string, Locale> = {
en,
es: {
common: {
loading: 'Cargando...',
error: 'Error',
noResults: 'Sin resultados',
delete: 'Eliminar',
call: 'Llamar',
cancel: 'Cancelar',
confirm: 'Confirmar',
previous: 'Anterior',
next: 'Siguiente',
perPage: 'Por página',
showing: 'Mostrando {start}-{end} de {total}',
play: 'Reproducir',
pause: 'Pausar',
},
voicemails: {
title: 'Buzón de voz',
loading: 'Cargando mensajes...',
empty: 'No hay mensajes de voz',
noUserId: 'Por favor establezca un ID de usuario',
transcription: 'Transcripción',
deleteConfirm: '¿Eliminar este mensaje de voz?',
deleteTitle: 'Eliminar mensaje',
progress: 'Progreso de reproducción',
},
callLogs: {
title: 'Registro de llamadas',
loading: 'Cargando llamadas...',
empty: 'No hay llamadas',
columns: {
date: 'Fecha',
direction: 'Dirección',
from: 'De',
to: 'Para',
duration: 'Duración',
status: 'Estado',
},
directions: {
inbound: 'Entrante',
outbound: 'Saliente',
internal: 'Interno',
},
statuses: {
completed: 'Completada',
noAnswer: 'Sin respuesta',
busy: 'Ocupado',
failed: 'Fallida',
voicemail: 'Buzón de voz',
},
},
},
};

const dialstack = initialize({
publishableKey: 'pk_live_YOUR_KEY',
});

function App() {
const [currentLocale, setCurrentLocale] = useState<string>('en');

return (
<DialstackComponentsProvider dialstack={dialstack} clientSecret={secret}>
<div className="p-6">
<div className="flex justify-between items-center mb-6">
<h1 className="text-2xl font-bold">{locales[currentLocale].callLogs.title}</h1>

<select
value={currentLocale}
onChange={(e) => setCurrentLocale(e.target.value)}
className="border rounded px-3 py-2"
>
<option value="en">English</option>
<option value="es">Español</option>
</select>
</div>

<CallLogs locale={locales[currentLocale]} />

<h2 className="text-xl font-bold mt-8 mb-4">{locales[currentLocale].voicemails.title}</h2>

<Voicemails userId="user_123" locale={locales[currentLocale]} />
</div>
</DialstackComponentsProvider>
);
}

TypeScript

Import the Locale type for type safety:

import type { Locale } from '@dialstack/sdk/locales';

const myLocale: Locale = {
// TypeScript will enforce the correct structure
};

Next Steps