Localization and RTL
ApexGantt's localization covers three independent concerns: the date and month labels in the timeline header (driven by a dayjs locale), the UI strings in the toolbar and context menu (driven by locale.messages), and the layout direction for RTL languages (driven by locale.direction).
Date locale
Pass a dayjs-compatible locale object to locale.dateLocale to localize every date, month, and weekday string in the timeline header:
import ApexGantt from 'apexgantt'
import localeFr from 'dayjs/locale/fr'
const gantt = new ApexGantt(document.getElementById('chart'), {
series: tasks,
locale: {
dateLocale: localeFr,
},
})
Install dayjs in your project if it is not already present — ApexGantt uses it internally but does not re-export locale files:
npm install dayjs
Then import any locale from dayjs/locale/*. Popular examples:
| Locale | Import path |
|---|---|
| French | dayjs/locale/fr |
| German | dayjs/locale/de |
| Spanish | dayjs/locale/es |
| Japanese | dayjs/locale/ja |
| Arabic | dayjs/locale/ar |
| Hebrew | dayjs/locale/he |
| Chinese (simplified) | dayjs/locale/zh-cn |
| Portuguese | dayjs/locale/pt |
RTL layout
Set locale.direction to 'rtl' to mirror the entire chart: the timeline flows right-to-left, the task list moves to the right side, and the dir="rtl" attribute is applied to the container element.
import ApexGantt from 'apexgantt'
import localeAr from 'dayjs/locale/ar'
const gantt = new ApexGantt(el, {
series: tasks,
locale: {
direction: 'rtl',
dateLocale: localeAr,
},
})
'auto' defers to the document or element's inherited dir attribute. The default is 'ltr'.
Switching direction at runtime requires a update() call:
gantt.update({ locale: { direction: 'rtl' } })
Overriding UI strings
locale.messages accepts a partial GanttMessages object. Any key you supply replaces the English default; unset keys keep their defaults.
const gantt = new ApexGantt(el, {
series: tasks,
locale: {
messages: {
addTask: 'Neue Aufgabe',
deleteSelected: 'Ausgewählte löschen',
undo: 'Rückgängig (Strg+Z)',
redo: 'Wiederholen (Strg+Y)',
exportAsSvg: 'Als SVG exportieren',
editTask: 'Aufgabe bearbeiten',
addChildTask: 'Unteraufgabe hinzufügen',
addSiblingTask: 'Geschwisteraufgabe hinzufügen',
indent: 'Einrücken',
outdent: 'Ausrücken',
deleteTask: 'Aufgabe löschen',
deleteTaskWithChildren: 'Löschen (mit Unteraufgaben)',
},
},
})
Full GanttMessages reference
| Key | Default | Context |
|---|---|---|
addTask | 'Add task' | Toolbar button |
deleteSelected | 'Delete selected' | Toolbar button |
undo | 'Undo (Ctrl+Z)' | Toolbar button |
redo | 'Redo (Ctrl+Y)' | Toolbar button |
exportAsSvg | 'Export as SVG' | Toolbar button |
editTask | 'Edit task' | Context menu |
addChildTask | 'Add child task' | Context menu |
addSiblingTask | 'Add sibling task' | Context menu |
indent | 'Indent' | Context menu |
outdent | 'Outdent' | Context menu |
deleteTask | 'Delete task' | Context menu (leaf) |
deleteTaskWithChildren | 'Delete (with children)' | Context menu (parent) |
formTaskName | 'Task Name' | Edit form label |
formStartDate | 'Start Date' | Edit form label |
formEndDate | 'End Date' | Edit form label |
formProgress | 'Progress (%)' | Edit form label |
formSubmit | 'Update' | Edit form button |
editTaskTitle | (name) => 'Edit Task: ' + name | Edit dialog title |
validationStartRequired | 'Start date is required' | Validation |
validationEndRequired | 'End date is required' | Validation |
validationEndAfterStart | 'End date must be after start date' | Validation |
validationNameRequired | 'Task name is required' | Validation |
validationProgressRequired | 'Progress is required' | Validation |
validationProgressRange | 'Progress must be between 0 and 100' | Validation |
addTaskRowLabel | '+ Add task' | Inline add-task row |
baselineLabel | 'Baseline:' | Baseline tooltip |
startLabel | 'Start:' | Baseline tooltip |
endLabel | 'End:' | Baseline tooltip |
Changing locale at runtime
update() merges locale settings shallowly:
gantt.update({
locale: {
direction: 'rtl',
dateLocale: localeAr,
messages: {
addTask: 'إضافة مهمة',
deleteSelected: 'حذف المحدد',
},
},
})
React example
import { useEffect, useState } from 'react'
import { ApexGanttChart } from 'react-apexgantt'
import type { GanttUserOptions } from 'react-apexgantt'
export default function LocalizedGantt() {
const [locale, setLocale] = useState<GanttUserOptions['locale']>({
direction: 'ltr',
})
const switchToArabic = async () => {
const localeAr = (await import('dayjs/locale/ar')).default
setLocale({ direction: 'rtl', dateLocale: localeAr })
}
return (
<div>
<button onClick={switchToArabic}>Switch to Arabic (RTL)</button>
<ApexGanttChart
tasks={tasks}
options={{ locale }}
height="500px"
/>
</div>
)
}
Vue example
<template>
<div>
<button @click="switchToArabic">Switch to Arabic (RTL)</button>
<ApexGanttChart :tasks="tasks" :options="ganttOptions" height="500px" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { GanttUserOptions } from 'vue-apexgantt'
const ganttOptions = ref<Partial<GanttUserOptions>>({
locale: { direction: 'ltr' },
})
const switchToArabic = async () => {
const localeAr = (await import('dayjs/locale/ar')).default
ganttOptions.value = {
locale: {
direction: 'rtl',
dateLocale: localeAr,
},
}
}
</script>