Internationalization
Comprehensive guide to internationalizing your calendar with custom translations, locales, and formatting.
The calendar supports comprehensive internationalization through multiple approaches: locale-based formatting, custom translations object, or translator functions. If both translations and translator are provided, the translator function takes priority.
Basic Locale Setup
Section titled “Basic Locale Setup”The simplest way to internationalize your calendar is by setting the locale and timezone props. This will automatically format dates according to the specified locale.
For proper date formatting, you must explicitly import the corresponding dayjs locale in your application. The calendar component uses dayjs internally but does not bundle all locales to keep the bundle size small.
dayjs is a peer dependency, so the calendar shares your app’s dayjs instance. Importing the locale once in your app registers it for the calendar too — no extra syncing of locale data between copies is needed.
import { IlamyCalendar } from '@ilamy/calendar';import 'dayjs/locale/fr'; // Import the French locale
function InternationalCalendar() { return ( <IlamyCalendar events={events} locale="fr" timezone="Europe/Paris" /> );}Custom Translations
Section titled “Custom Translations”For more control over the text displayed in your calendar, you can provide a custom translations object. This allows you to translate button labels, view names, and other UI text.
The translations prop takes the full Translations type: every key must be present, so a missing translation is a compile error rather than a label that silently stays in English. To change only a few labels, spread defaultTranslations first.
import { IlamyCalendar, defaultTranslations, type Translations } from '@ilamy/calendar';
const frenchTranslations: Translations = { ...defaultTranslations, // every key, in English, until you translate it today: 'Aujourd\'hui', month: 'Mois', week: 'Semaine', day: 'Jour', year: 'Année', previous: 'Précédent', next: 'Suivant', // Translate the rest of the keys};
function TranslatedCalendar() { return ( <IlamyCalendar events={events} locale="fr" translations={frenchTranslations} firstDayOfWeek="monday" /> );}Translator Function
Section titled “Translator Function”For dynamic translations or integration with existing i18n libraries, you can provide a translator function. It receives a translation key and returns the translated string. Return the key itself for a label you do not translate.
import { IlamyCalendar, type TranslatorFunction } from '@ilamy/calendar';
const translations: Record<string, string> = { today: 'Aujourd\'hui', month: 'Mois', week: 'Semaine', day: 'Jour', year: 'Année', previous: 'Précédent', next: 'Suivant',};
const translator: TranslatorFunction = (key) => translations[key] ?? key;
function TranslatorCalendar() {
return ( <IlamyCalendar events={events} locale="fr" translator={translator} firstDayOfWeek="monday" /> );}Integration with i18n Libraries
Section titled “Integration with i18n Libraries”You can easily integrate the calendar with popular i18n libraries like react-i18next, react-intl, or others.
react-i18next Integration
Section titled “react-i18next Integration”import { IlamyCalendar } from '@ilamy/calendar';import { useTranslation } from 'react-i18next';
function I18nCalendar() { const { t, i18n } = useTranslation();
const translator = (key: string) => t(`calendar.${key}`);
return ( <IlamyCalendar events={events} locale={i18n.language} translator={translator} firstDayOfWeek="monday" /> );}react-intl Integration
Section titled “react-intl Integration”import { IlamyCalendar } from '@ilamy/calendar';import { useIntl } from 'react-intl';
function IntlCalendar() { const intl = useIntl();
const translator = (key: string) => intl.formatMessage({ id: `calendar.${key}` });
return ( <IlamyCalendar events={events} locale={intl.locale} translator={translator} firstDayOfWeek="monday" /> );}Available Translation Keys
Section titled “Available Translation Keys”The calendar supports a comprehensive set of translation keys for static UI text — common actions, event properties, recurrence options, and view types. You can find the complete list of available keys via the TranslationKey type which is exported from the calendar package.
Month and weekday names are not translation keys. They are localized through the active dayjs locale, so set the locale prop and import the matching dayjs locale (see Basic Locale Setup). Providing january/monday/mon-style keys via translations has no effect.
Changed in v1.8.0: the month-name and day-name keys were removed from the Translations type. If you previously localized month or weekday names through translations, switch to a dayjs locale instead (e.g. import 'dayjs/locale/de' then locale="de").
import type { TranslationKey } from '@ilamy/calendar';
// The TranslationKey type includes all available keys:// - Common actions: today, create, update, delete, cancel// - Pickers: pickDate, selectTime, searchTime, noTimeFound, previousMonth, nextMonth, ...// - Event related: event, events, title, description, location, etc.// - Recurrence: repeat, daily, weekly, monthly, yearly, etc.// - View types: month, week, day, year// (Month and weekday names come from the dayjs locale, not these keys.)
const myTranslator = (key: TranslationKey) => { // Your translation logic here return myDictionary[key] ?? key;};Keys added in 3.3
Section titled “Keys added in 3.3”3.3 translates the date and time pickers and the month and year navigation of the date pickers, which were hard-coded in English. That adds nine keys: selectTime, noTimeFound, pickDate, previousMonth, nextMonth, previousYear, nextYear, previousYears and nextYears. A translations object written for 3.2 does not type-check until it has them; add them, or spread defaultTranslations and translate them later. A translator function needs no code change, but your dictionary needs these keys too, or the key itself is shown.
TypeScript type definitions for internationalization features.
// In v2 `Translations` is a derived type alias (not an interface): every key// from the canonical English dictionary, mapped to a string.type Translations = Record<keyof typeof defaultTranslations, string>;
// Translation key type (exported from package)type TranslationKey = keyof Translations;
// Translator function typetype TranslatorFunction = (key: TranslationKey | string) => string;import { defaultTranslations, type TranslatorFunction, type Translations } from '@ilamy/calendar';
const frenchTranslations: Translations = { ...defaultTranslations, today: 'Aujourd\'hui', month: 'Mois', // ... translate the other keys};
const dynamicTranslator: TranslatorFunction = (key) => { // Custom translation logic return getTranslation(key);};Best Practices
Section titled “Best Practices”Priority Order
Section titled “Priority Order”When both translations and translator are provided, the translator function takes priority. Use this to your advantage:
- Provide fallback translations with the
translationsprop - Use
translatorfor dynamic or complex translation logic - The translator can fall back to the static translations when needed
Performance
Section titled “Performance”- Memoize your translator function to avoid unnecessary re-renders
- Use static translations objects when possible for better performance
- Consider lazy loading translations for large applications
Locale Setup
Section titled “Locale Setup”- Always set the
localeprop for proper date formatting. - Import necessary
dayjslocales in your entry file or component. - If your application supports many languages, you might need to import multiple locales:
import 'dayjs/locale/en';import 'dayjs/locale/fr';import 'dayjs/locale/es';// etc.
- Set
firstDayOfWeekto your locale’s convention. The calendar does not take the week start from thedayjslocale (fr and de start on Monday, ar on Saturday):firstDayOfWeekdecides it,'sunday'by default. - Use appropriate timezone settings for your users’ locations.