Localization
Each prop on this page does one job. translations changes the words. locale picks plural forms. rtl flips the layout. Set them independently.
translations
Section titled “translations”| Type | DataEditorTranslations |
Override any UI string. Pass a partial object, and the SDK replaces only the keys you provide.
This is the one prop that changes the language. Setting locale alone leaves the UI in English.
<DataEditor translations={{ dataEditor: { modal: { editTitle: "Edit Employees", importTitle: "Import Employee Data", }, footer: { submit: "Save Changes", }, }, ui: { select: { noResults: "No matches", }, }, }} .../>Defaults
Section titled “Defaults”Keys sit under two roots. dataEditor holds the SDK’s own screens, from the import wizard to the grid, the filters, and the footer. ui holds the shared controls rendered inside them, such as the close button on a modal, the empty result text in a dropdown, and the month names in the date picker. Translate both roots to get the whole interface in one language.
Month names come from locale on their own, so a date picker set to "fr" reads in French with nothing passed. The same names read a spelled-out month during an import, so 11 octobre 2025 arrives as a date. Set ui.calendar.months or ui.calendar.monthsShort to replace them.
Pass any subset of the tree below.
{ "ui": { "button": { "defaultAriaLabel": "Button" }, "calendar": { "previousMonth": "Previous month", "nextMonth": "Next month", "months": { "january": "January", "february": "February", "march": "March", "april": "April", "may": "May", "june": "June", "july": "July", "august": "August", "september": "September", "october": "October", "november": "November", "december": "December" }, "monthsShort": { "january": "Jan", "february": "Feb", "march": "Mar", "april": "Apr", "may": "May", "june": "Jun", "july": "Jul", "august": "Aug", "september": "Sep", "october": "Oct", "november": "Nov", "december": "Dec" }, "weekDays": { "mo": "Mo", "tu": "Tu", "we": "We", "th": "Th", "fr": "Fr", "sa": "Sa", "su": "Su" }, "weekDaysFull": { "mo": "Monday", "tu": "Tuesday", "we": "Wednesday", "th": "Thursday", "fr": "Friday", "sa": "Saturday", "su": "Sunday" }, "label": "Calendar", "selectMonth": "{{month}}, select month", "selectYear": "{{year}}, select year" }, "datePicker": { "placeholder": "DD/MM/YYYY", "openCalendar": "Open calendar", "clearSelection": "Clear selection" }, "input": { "clearField": "Clear field", "showPassword": "Show password", "hidePassword": "Hide password", "switchToAm": "Switch to AM", "switchToPm": "Switch to PM" }, "select": { "noResults": "No results", "clearSelection": "Clear selection" }, "tag": { "remove": "Remove" }, "modal": { "closeLabel": "Close" }, "drawer": { "closeLabel": "Close" }, "confirmDialog": { "cancel": "Cancel" }, "menu": { "submenuAriaLabel": "{{text}} submenu" }, "formField": { "optional": "Optional" } }, "dataEditor": { "modal": { "importTitle": "Import Data", "editTitle": "Edit Data", "viewTitle": "View Data" }, "confirmClose": { "title": "Discard changes?", "text": "You have unsaved changes. Are you sure you want to close?", "action": "Discard" }, "confirmSubmit": { "title": "Confirm submission", "text": "You are about to submit the following changes:", "createRows_one": "{{count}} new row will be created", "createRows_other": "{{count}} new rows will be created", "updateRows_one": "{{count}} row will be updated", "updateRows_other": "{{count}} rows will be updated", "deleteRows_one": "{{count}} row will be deleted", "deleteRows_other": "{{count}} rows will be deleted", "bannerTitle_one": "{{count}} row has errors", "bannerTitle_other": "{{count}} rows have errors", "action": "Submit" }, "footer": { "submit": "Submit", "submitBlockedByErrors": "Fix errors before submitting", "import": "Import", "next": "Next", "cancel": "Cancel", "back": "Back", "export": "Export", "exportAll": "Export all", "exportFiltered": "Export filtered", "csvFormat": "Comma-separated values (.csv)", "tsvFormat": "Tab-separated values (.tsv)", "excelFormat": "Microsoft Excel (.xlsx)", "jsonFormat": "JSON (.json)", "xmlFormat": "XML (.xml)" }, "statusBar": { "totalRows_one": "{{total}} row", "totalRows_other": "{{total}} rows", "filteredRows_one": "{{filtered}} of {{total}} row", "filteredRows_other": "{{filtered}} of {{total}} rows" }, "toast": { "clipboardWriteFailed": "The browser blocked the copy to the clipboard. You can paste inside this table.", "dismiss": "Dismiss", "rowMayNotBeVisible": "Row has been added but may not be visible due to active filters or sorting" }, "grid": { "emptyTitle": "No data", "emptyText": "Import data or add rows manually", "loading": "Loading data...", "emptyCell": "Empty", "a11y": { "cellEditor": "Edit {{column}}, row {{row}}", "cellFocus": "Row {{row}}, {{column}}: {{value}}", "cellFocusEmpty": "Row {{row}}, {{column}}: empty", "cellInvalid": "Invalid: {{messages}}", "cellMisplaced": "Misplaced: {{messages}}", "contextMenu": "Grid actions", "gridLabel": "Data editor", "selectAll": "All cells selected", "rowsSelected_one": "{{count}} row selected", "rowsSelected_other": "{{count}} rows selected", "columnsSelected_one": "{{count}} column selected", "columnsSelected_other": "{{count}} columns selected" }, "contextMenu": { "cut": "Cut", "cutCells": "Cut ({{count}})", "copy": "Copy", "copyCells": "Copy ({{count}})", "paste": "Paste", "deleteRow": "Delete row", "deleteRows": "Delete rows ({{count}})", "restoreRow": "Restore row", "restoreRows": "Restore rows ({{count}})", "sortAsc": "Sort A to Z", "sortDesc": "Sort Z to A", "sortRemove": "Remove sorting", "insertAbove": "Insert row above", "insertBelow": "Insert row below", "duplicateRow": "Duplicate row", "cutRow": "Cut row", "cutRows": "Cut rows ({{count}})", "copyRow": "Copy row", "copyRows": "Copy rows ({{count}})", "clearRow": "Clear row", "clearRows": "Clear rows ({{count}})", "clearAll": "Clear all", "pin": "Pin column", "pinColumns": "Pin columns", "unpin": "Unpin column", "unpinColumns": "Unpin columns", "cutColumn": "Cut column", "copyColumn": "Copy column", "pasteColumn": "Paste column", "lockColumn": "Lock column", "lockColumns": "Lock columns", "lockedCannotClear": "Can't clear a locked column", "lockedCannotDelete": "Can't delete a locked column", "lockedCannotRevert": "Can't revert a locked column", "lockedCannotUnlock": "This column was locked by configuration", "unlockColumn": "Unlock column", "unlockColumns": "Unlock columns", "clearColumn": "Clear column", "clearColumns": "Clear columns", "deleteColumn": "Delete column", "deleteColumns": "Delete columns", "editColumn": "Edit column", "transform": "Transform", "transformMerge": "Merge", "transformSplit": "Split", "formula": "Formula", "lockedCannotFormula": "Can't apply a formula to a locked column", "revertChanges": "Revert changes", "markAsCorrect": "Mark as correct" }, "formulaModal": { "title": "Apply formula", "apply": "Apply", "applyToRows_one": "Apply to {{count}} row", "applyToRows_other": "Apply to {{count}} rows", "inputLabel": "Formula", "placeholder": "=UPPER(value) · Type @ to browse", "groupFunctions": "Functions", "groupColumns": "Columns", "groupKeywords": "Keywords", "keywordValue": "Current cell value", "preview": "Preview", "errors": { "unexpected-character": "'{{char}}' isn't valid here", "unexpected-escape": "Invalid escape '\\{{char}}' — only \\} and \\\\ are allowed inside @{}", "unterminated-column-ref": "@{...} isn't closed — add a closing }", "expected-equals": "Formulas must start with =", "expected-expression": "Add a function, value, or @column after =", "expected-open-paren": "Missing '(' after {{name}}", "expected-close-paren": "Missing closing ')'", "expected-column-name": "Add a column name after @ — e.g. @Name or @{First Name}", "unexpected-token": "'{{token}}' isn't expected here", "unknown-function": "No function named '{{name}}'", "unknown-column": "No column named '{{name}}'", "arity-mismatch-too-few": "{{name}} expects at least {{min}} arguments — got {{actual}}", "arity-mismatch-too-many": "{{name}} takes at most {{max}} arguments — got {{actual}}", "function-not-in-expression-mode": "'{{name}}' can't be used here — use Merge or Split from the Transform menu", "column-not-numeric": "'{{name}}' is not a number column — arithmetic requires number columns" } }, "formulas": { "UPPER": { "label": "Uppercase" }, "LOWER": { "label": "Lowercase" }, "TRIM": { "label": "Trim whitespace" }, "CAPITALIZE": { "label": "Capitalize" }, "ROUND": { "label": "Round" }, "ROUND_UP": { "label": "Round up" }, "ROUND_DOWN": { "label": "Round down" }, "ABS": { "label": "Absolute value" }, "CLEAR": { "label": "Clear" }, "CONCAT": { "label": "Concatenate" }, "LEFT": { "label": "Left" }, "RIGHT": { "label": "Right" }, "MID": { "label": "Mid" }, "SUBSTITUTE": { "label": "Substitute" }, "MERGE": { "label": "Merge columns" }, "SPLIT": { "label": "Split column" } }, "transformMerge": { "addColumn": "Add column", "apply": "Apply", "deleteSource": "Delete source columns", "deleteSourceDescription": "Columns added during import can be deleted. Schema columns will remain.", "from": "From", "into": "Into", "joinWith": "Join with", "joinWithPlaceholder": "e.g. space, comma", "preview": "Preview", "removeColumn": "Remove column", "applyToRows_one": "Apply to {{count}} row", "applyToRows_other": "Apply to {{count}} rows", "selectColumn": "Select column", "selectColumnNumber": "Select column {{number}}", "title": "Merge" }, "transformSplit": { "addColumn": "Add column", "apply": "Apply", "applyToRows_one": "Apply to {{count}} row", "applyToRows_other": "Apply to {{count}} rows", "deleteSource": "Delete source column", "deleteSourceDescription": "Columns added during import can be deleted. Schema columns will remain.", "from": "From", "into": "Into", "preview": "Preview", "removeColumn": "Remove column", "selectColumn": "Select column", "selectColumnNumber": "Select column {{number}}", "splitBy": "Split by", "splitByPlaceholder": "e.g. space, comma", "title": "Split" }, "phase": { "splitting": "Splitting columns...", "merging": "Merging columns...", "pasting": "Pasting data...", "clearing": "Clearing cells...", "filling": "Filling cells...", "sorting": "Sorting rows...", "undoing": "Reverting changes...", "redoing": "Reapplying changes...", "reverting": "Reverting changes...", "deleting": "Deleting rows...", "deletingSource": "Removing data source...", "importing": "Importing data...", "transforming": "Transforming...", "default": "Processing..." } }, "dataSources": { "title": "Data Sources", "importData": "Import data", "addRow": "Add row", "manuallyAdded": "Manually added", "existingData": "Existing data", "addDataSource": "Add data source", "show": "Show", "hide": "Hide", "remove": "Remove", "confirmRemove": { "title": "Remove data source?", "text": "All data imported from this source will be removed.", "action": "Remove" } }, "filters": { "title": "Filters", "search": "Search", "replace": "Replace", "findAndReplace": "Find & Replace", "searchMode": "Search mode", "matchCase": "Match case", "matchEntireCell": "Match entire cell", "rows": "Rows", "columns": "Columns", "searchInColumns": "Search in columns", "allColumns": "All columns", "rowsWithErrors": "Rows with errors", "editedRows": "Changed rows", "newRows": "New rows", "rowsWithEmptyCells": "Rows with empty cells", "rowsWithMisplacedValues": "Rows with misplaced values", "deletedRows": "Deleted rows", "previousOccurrence": "Previous occurrence", "nextOccurrence": "Next occurrence", "zeroResults": "No results found", "allValues": "All values", "min": "Min", "max": "Max", "from": "From", "to": "To", "rangeMin": "{{label}}, minimum", "rangeMax": "{{label}}, maximum", "rangeFrom": "{{label}}, from", "rangeTo": "{{label}}, to", "replaceAll": "Replace all", "resetFilters": "Reset filters", "showMore": "View error details", "showLess": "Hide error details" }, "undoRedo": { "undo": "Undo", "redo": "Redo" }, "validation": { "alreadyExists": "Already exists in your database", "endDateBeforeStart": "End date must be after start date", "invalidDate": "Invalid date", "invalidEmail": "Invalid email address", "invalidFormat": "Invalid format", "invalidNumber": "Invalid number", "invalidOption": "Invalid option", "invalidTime": "Invalid time", "outOfRange": "Out of range", "required": "This field is required", "structuralMismatch": "This might be in the wrong column.", "tooManyDecimals": "Too many decimal places", "tooPreciseTime": "Too precise for this column", "valueMustBeUnique": "Value must be unique" }, "license": { "loading": "Loading data editor" }, "connecting": { "label": "Connecting to server…" }, "errors": { "RENDER_ERROR": { "title": "Something went wrong", "text": "Please close this window and try again" }, "license": { "invalid": { "title": "Invalid license", "text": "Please contact support for assistance." }, "missing": { "title": "Missing API key", "text": "No API key was provided. Please configure a valid API key." }, "domain_not_allowed": { "title": "Domain not allowed", "text": "This domain is not authorized for this license. Please check your domain settings." }, "subscription_inactive": { "title": "Subscription inactive", "text": "Your subscription is no longer active. Please renew to continue." } } }, "uploader": { "steps": { "selectFiles": "Select files", "headerSelection": "Header selection", "headerSelectionOf": "Header selection ({{current}} of {{total}})", "matchColumns": "Match columns", "matchColumnsOf": "Match columns ({{current}} of {{total}})", "matchValues": "Match values", "addOrUpdate": "Add or update" }, "uploadFile": { "parseError": "Failed to parse file", "clickToUpload": "Click to upload", "orDragAndDrop": "or drag and drop", "formats": "CSV, TSV, XLSX, JSON, XML", "csvWarning_one": "{{count}} row had formatting issues (row {{rows}})", "csvWarning_other": "{{count}} rows had formatting issues (rows {{rows}})", "customEmpty": "No tables were found in this file", "customFailed": "Could not process the file", "downloadExample": "Download sample file", "fileInputLabel": "Choose files to upload", "fileTooLarge": "The file is too large to process", "reset": "Reset", "uploading": "Uploading file" }, "remoteSources": { "browseFile": "Browse file", "emptyData": "The source returned no data", "fetchError": "Failed to load data" }, "headerSelection": { "noHeaderLabel": "My data has no header row", "previewGridLabel": "File preview" }, "import": { "collapsedFiles_one": "{{count}} file added no new rows. All of its rows are already in the table.", "collapsedFiles_other": "{{count}} files added no new rows. All of their rows are already in the table." }, "matchColumns": { "allMatched": "All columns are matched", "banner": "Some columns could not be automatically matched", "changeHeaderRow": "Change header row", "importedColumns": "Imported columns", "matchedCount": "{{matched}}/{{total}} matched", "targetColumns": "Target columns", "selectColumnPlaceholder": "Select column", "showMatched": "Show matched", "syntheticColumn": "C{{index}}", "syntheticColumnValue": "C{{index}}: {{value}}", "bestMatch": "Best match", "createColumn": "Create column", "createColumnNameLabel": "Column name", "createColumnNamePlaceholder": "Enter column name", "createColumnNameTaken": "A column with this name already exists", "createColumnSubmit": "Create", "createColumnTitle": "Create column", "editColumnSubmit": "Save", "editColumnTitle": "Edit column", "createColumnWarning": "A matching column already exists", "newColumnTag": "New", "sampleValues": "Example values", "sampleValuesEmpty": "No values in this column", "showSampleValues": "Show example values from {{column}}", "unmatchedWarning": "Unmatched columns won't be imported. Match this column to keep the data. You can transform columns after importing." }, "sheetPreview": { "cancel": "Cancel processing", "emptySheet": "Empty sheet", "rowCount_one": "{{count}} row", "rowCount_other": "{{count}} rows" }, "matchValues": { "importedValues": "Imported values", "matchedCount": "{{matched}}/{{total}} matched", "targetValue": "Target value", "selectValuePlaceholder": "Select value", "showAll": "Show all", "showMatched": "Show matched", "allMatched": "All values are matched", "tooManyValues": "Showing first {{shown}} of {{total}} values", "unmatchedWarning": "Unmatched values won't be imported. Match this value to keep the data. You can edit values after importing.", "createAllOptions": "Create all options", "createOption": "Create option", "createOptionTitle": "Create option", "createOptionNameLabel": "Option name", "createOptionNamePlaceholder": "Enter option name", "createOptionNameTaken": "This option already exists", "createOptionSubmit": "Create", "reapplySeparator": "Reset to auto-detected separator", "separator": "Separator", "separatedBy": "Values separated by" }, "addOrUpdate": { "addEvery": "Add every row", "addEveryHint": "Every row becomes a new entry, even if it repeats one you already have.", "updateBy": "Update by {{column}}" } }, "chat": { "emptyTitle": "What would you like to fix?", "header": "Chat with AI", "inputLabel": "Ask AI about your data", "placeholder": "Ask AI...", "send": "Send" }, "common": { "cancel": "Cancel", "collapse": "Collapse", "dropToImport": "Drop file to upload", "expand": "Expand", "remove": "Remove", "save": "Save", "search": "Search" } }}locale
Section titled “locale”| Type | string |
| Default | "en" |
BCP 47 locale tag, for example "en", "fr", or "ar". It selects the plural form for keys that end in _zero, _one, _two, _few, _many, or _other, using Intl.PluralRules. When no key matches the selected category, the SDK falls back to _other. An invalid tag falls back to "en".
That is the whole job. locale does not load translations and does not switch the language.
locale answers for words, the browser answers for digits. Month names are words, so a date written 5 luglio 2026 is read when locale is "it". Whether 03/04/2026 is the third of April or the fourth of March is an order of digits, and so is whether 1,234 is a grouped thousand or a decimal — a file came off somebody’s machine and their spreadsheet wrote it in that machine’s locale, so the SDK asks the browser. The two axes are read separately: en-GB writes dates day-first and numbers the American way, and both are honoured.
A file that explains itself overrides both. One value with a part above 12 settles the date order for the column, and one value carrying both separators settles the number punctuation.
Strings passed to loadData follow neither. They come from your own database rather than from a spreadsheet, so numbers are read at a fixed 1,234.56 and dates are settled by the column: a value with a part above 12 anywhere in the column decides it for the rest, ISO is always accepted, and a column of nothing but ambiguous values stays text and is flagged.
Set it when your language has plural rules that differ from English. Arabic has six forms, Russian has three, Japanese has one.
<DataEditor locale="ar" translations={arabicTranslations} ... />| Type | boolean |
| Default | false |
Enable right-to-left layout. Set to true for Arabic, Hebrew, and other RTL languages. Affects grid direction, text alignment, and scrollbar position. Exports to CSV, TSV, and XLSX also write the columns in reverse order, so the first column lands on the right.
rtl is independent of locale. Setting one does not set the other.
<DataEditor locale="ar" rtl={true} translations={arabicTranslations} ... />