Internationalization (i18n)
Every user-facing string the picker renders comes from a single label set. Override any subset with the labels option to translate the UI, reword copy, or white-label it — there's nothing else to wire up.
The labels option
Pass a Partial<FilePickerLabels>. Anything you leave out falls back to the built-in English default, so you only supply the strings you actually want to change:
new FilePicker({
adapter,
labels: {
title: 'Médiathèque',
upload: 'Téléverser',
done: 'Terminé',
},
})The framework bindings spread FilePickerOptions, so labels works the same everywhere — pass it as a prop or option to <FilePicker> in React, Vue, Svelte, Solid or the Web Component.
Static vs. function labels
Most labels are plain strings. A handful are functions that receive interpolation values and return the finished string — use them to place counts, names and numbers exactly where your language needs them:
| Label | Signature | Default |
|---|---|---|
selected | (n) => string | 2 selected |
results | (n) => string | 1 result / 5 results |
selectAction | (n) => string | Select 3 / Done |
perPageOption | (n) => string | 24 / page |
pageStatus | (page, last, total) => string | 2 / 5 · 108 items |
uploaded | (n) => string | Uploaded 3 files |
uploadSkipped | (n) => string | 2 files skipped — wrong type |
editMeta | (type, mime, size) => string | Type: image · image/jpeg · 812 KB |
deleteFileConfirm | (name) => string | Delete "photo.jpg"? … |
deleteFolderConfirm | (name) => string | Delete "Branding"? … |
createFolder | (name) => string | Create folder "Press kit" |
maxSelection | (n) => string | You can select up to 5 items |
Because they're ordinary functions, you get full control over pluralization and word order:
new FilePicker({
adapter,
labels: {
selected: (n) => `${n} sélectionné${n === 1 ? '' : 's'}`,
pageStatus: (page, last, total) =>
total > 0
? `Page ${page} / ${last} · ${total} élément${total === 1 ? '' : 's'}`
: `Page ${page} / ${last}`,
},
})defaultLabels
The complete English set is exported as defaultLabels, and the FilePickerLabels type describes its shape — both come from the core package:
import { defaultLabels } from '@anil-labs/file-picker-core'
import type { FilePickerLabels } from '@anil-labs/file-picker-core'Import defaultLabels when you want to see every key, reuse a default while overriding its neighbours, or build a full translation on top of it. Because labels merges over defaultLabels, a partial object is all the picker needs — but typing a complete translation as FilePickerLabels lets TypeScript flag any key you forget.
A French example
import { FilePicker } from '@anil-labs/file-picker-core'
import type { FilePickerLabels } from '@anil-labs/file-picker-core'
const fr: Partial<FilePickerLabels> = {
title: 'Médiathèque',
filters: 'Filtres',
upload: 'Téléverser',
done: 'Terminé',
searchPlaceholder: 'Rechercher des fichiers…',
allTypes: 'Tous les types',
clearFilters: 'Effacer les filtres',
refresh: 'Actualiser',
loading: 'Chargement des médias',
emptyTitle: 'Votre médiathèque est vide',
emptyBody: 'Téléversez votre premier fichier pour commencer.',
emptyUpload: 'Téléverser des fichiers',
filteredTitle: 'Aucun fichier ne correspond à vos filtres',
filteredBody: 'Essayez une autre recherche ou effacez les filtres.',
edit: 'Modifier',
delete: 'Supprimer',
cancel: 'Annuler',
selected: (n) => `${n} sélectionné${n === 1 ? '' : 's'}`,
results: (n) => (n === 1 ? '1 résultat' : `${n} résultats`),
uploaded: (n) => (n === 1 ? '1 fichier téléversé' : `${n} fichiers téléversés`),
deleteFileConfirm: (name) => `Supprimer « ${name} » ? Cette action est irréversible.`,
pageStatus: (page, last, total) =>
total > 0
? `${page} / ${last} · ${total} élément${total === 1 ? '' : 's'}`
: `${page} / ${last}`,
}
new FilePicker({ adapter, labels: fr })See the API reference for the labels option and the full FilePickerLabels type.